<!DOCTYPE html>
<html
  data-n-head-ssr
  lang="zh"
  data-n-head="%7B%22lang%22:%7B%22ssr%22:%22zh%22%7D%7D"
>
  <head>
    <title>Vue 源码解读（2）—— Vue 初始化过程 - 掘金</title>
    <meta data-n-head="ssr" charset="utf-8" />
    <meta
      data-n-head="ssr"
      name="viewport"
      content="width=device-width, initial-scale=1, user-scalable=no, viewport-fit=cover"
    />
    <meta
      data-n-head="ssr"
      name="apple-itunes-app"
      content="app-id=987739104"
    />
    <meta data-n-head="ssr" name="theme-color" content="#ffffff" />
    <meta data-n-head="ssr" name="msapplication-TileColor" content="#da532c" />
    <meta
      data-n-head="ssr"
      vmid="description"
      name="description"
      content="详细讲解了 Vue 的初始化过程都做了哪些事 ..........................."
    />
    <meta
      data-n-head="ssr"
      vmid="keywords"
      name="keywords"
      content="JavaScript,Vue.js,前端"
    />
    <link
      data-n-head="ssr"
      rel="preconnect"
      href="//unpkg.byted-static.com/"
      crossorigin="anonymous"
    />
    <link
      data-n-head="ssr"
      rel="preconnect"
      href="//lf3-cdn-tos.bytescm.com"
      crossorigin="anonymous"
    />
    <link
      data-n-head="ssr"
      rel="preconnect"
      href="//mcs.snssdk.com"
      crossorigin="anonymous"
    />
    <link
      data-n-head="ssr"
      rel="preconnect"
      href="//i.snssdk.com"
      crossorigin="anonymous"
    />
    <link
      data-n-head="ssr"
      rel="dns-prefetch"
      href="//lf3-short.ibytedapm.com"
    />
    <link
      data-n-head="ssr"
      rel="dns-prefetch"
      href="//lf3-cdn-tos.bytescm.com"
    />
    <link data-n-head="ssr" rel="dns-prefetch" href="//api.juejin.cn" />
    <link
      data-n-head="ssr"
      rel="dns-prefetch"
      href="//lf-cdn-tos.bytescm.com"
    />
    <link
      data-n-head="ssr"
      rel="dns-prefetch"
      href="//unpkg.byted-static.com"
    />
    <link data-n-head="ssr" rel="dns-prefetch" href="//p1-juejin.byteimg.com" />
    <link data-n-head="ssr" rel="dns-prefetch" href="//p3-juejin.byteimg.com" />
    <link data-n-head="ssr" rel="dns-prefetch" href="//p6-juejin.byteimg.com" />
    <link data-n-head="ssr" rel="dns-prefetch" href="//p9-juejin.byteimg.com" />
    <link data-n-head="ssr" rel="dns-prefetch" href="//p1-jj.byteimg.com" />
    <link data-n-head="ssr" rel="dns-prefetch" href="//p2-jj.byteimg.com" />
    <link data-n-head="ssr" rel="dns-prefetch" href="//p6-jj.byteimg.com" />
    <link data-n-head="ssr" rel="dns-prefetch" href="//p9-jj.byteimg.com" />
    <link data-n-head="ssr" rel="dns-prefetch" href="//mcs.snssdk.com" />
    <link data-n-head="ssr" rel="dns-prefetch" href="//i.snssdk.com" />
    <link
      data-n-head="ssr"
      rel="apple-touch-icon"
      sizes="180x180"
      href="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web//static/favicons/apple-touch-icon.png"
    />
    <link
      data-n-head="ssr"
      rel="icon"
      type="image/png"
      sizes="32x32"
      href="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web//static/favicons/favicon-32x32.png"
    />
    <link
      data-n-head="ssr"
      rel="icon"
      type="image/png"
      sizes="16x16"
      href="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web//static/favicons/favicon-16x16.png"
    />
    <link
      data-n-head="ssr"
      rel="mask-icon"
      href="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web//static/favicons/safari-pinned-tab.svg"
      color="#1E80FF"
    />
    <link
      data-n-head="ssr"
      rel="manifest"
      href="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web//static/favicons/site.webmanifest"
    />
    <link
      data-n-head="ssr"
      rel="search"
      title="掘金"
      href="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web//static/search.xml"
      type="application/opensearchdescription+xml"
    />
    <link
      data-n-head="ssr"
      rel="stylesheet"
      href="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web//static/bytedesign.min.css"
    />
    <link
      data-n-head="ssr"
      rel="canonical"
      href="https://juejin.cn/post/6950084496515399717"
    />
    <script
      data-n-head="ssr"
      type="text/javascript"
      data-sdk-glue-default="load"
      src="https://lf-headquarters-speed.yhgfb-cn-static.com/obj/rc-client-security/web/glue/1.0.0.8/sdk-glue.js"
    ></script>
    <script
      data-n-head="ssr"
      type="text/javascript"
      data-sdk-glue-default="init"
    >
      (function () {
        var options = {
          bdms: {
            aid: 2608,
            paths: [
              "/growth_api/v1/publish_benefit_history",
              "/growth_api/v1/check_in",
              "/growth_api/v1/lottery/draw",
              "/growth_api/v1/lottery/ten_draw",
              "/web_shorten",
            ],
          },
        };
        window._SdkGlueInit(options);
      })();
    </script>
    <script
      data-n-head="ssr"
      vmid="slardar"
      type="text/javascript"
      crossorigin="anonymous"
    >
      (function (w, d, u, b, n, pc, ga, ae, po, s, p, e, t, pp) {
        pc = "precollect";
        ga = "getAttribute";
        ae = "addEventListener";
        po = "PerformanceObserver";
        s = function (m) {
          p = [].slice.call(arguments);
          p.push(Date.now(), location.href);
          (m == pc ? s.p.a : s.q).push(p);
        };
        s.q = [];
        s.p = { a: [] };
        w[n] = s;
        e = document.createElement("script");
        e.src = u + "?bid=" + b + "&globalName=" + n;
        e.crossOrigin =
          u.indexOf("sdk-web") > 0 ? "anonymous" : "use-credentials";
        d.getElementsByTagName("head")[0].appendChild(e);
        if (ae in w) {
          s.pcErr = function (e) {
            e = e || w.event;
            t = e.target || e.srcElement;
            if (t instanceof Element || t instanceof HTMLElement) {
              if (t[ga]("integrity")) {
                w[n](pc, "sri", t[ga]("href") || t[ga]("src"));
              } else {
                w[n](pc, "st", {
                  tagName: t.tagName,
                  url: t[ga]("href") || t[ga]("src"),
                });
              }
            } else {
              w[n](pc, "err", e.error || e.message);
            }
          };
          s.pcRej = function (e) {
            e = e || w.event;
            w[n](pc, "err", e.reason || (e.detail && e.detail.reason));
          };
          w[ae]("error", s.pcErr, true);
          w[ae]("unhandledrejection", s.pcRej, true);
        }
        if ("PerformanceLongTaskTiming" in w) {
          pp = s.pp = { entries: [] };
          pp.observer = new PerformanceObserver(function (l) {
            pp.entries = pp.entries.concat(l.getEntries());
          });
          pp.observer.observe({
            entryTypes: [
              "longtask",
              "largest-contentful-paint",
              "layout-shift",
            ],
          });
        }
      })(
        window,
        document,
        "https://lf3-short.ibytedapm.com/slardar/fe/sdk-web/browser.cn.js",
        "2608",
        "SlardarWeb"
      );
    </script>
    <script
      data-n-head="ssr"
      type="text/javascript"
      src="//unpkg.byted-static.com/latest/byted-imagex/slardar-plugin/browser/imageReport.js"
    ></script>
    <script data-n-head="ssr" type="application/ld+json">
      [
        {
          "@context": "https://schema.org",
          "@type": "BlogPosting",
          "mainEntityOfPage": {
            "@type": "WebPage",
            "@id": "https://juejin.cn/post/6950084496515399717"
          },
          "headline": "Vue 源码解读（2）—— Vue 初始化过程",
          "description": "详细讲解了 Vue 的初始化过程都做了哪些事 ...........................",
          "image": [
            "https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4cf0e7b553704152a23879301ed0c58c~tplv-k3u1fbpfcp-watermark.image"
          ],
          "author": { "@type": "Organization", "name": "李永宁" },
          "publisher": {
            "@type": "Organization",
            "name": "掘金",
            "logo": {
              "@type": "ImageObject",
              "url": "//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/e08da34488b114bd4c665ba2fa520a31.svg"
            }
          },
          "datePublished": "2021-04-12T09:58:21+08:00",
          "dateModified": "2022-02-22T08:24:47+08:00"
        },
        {
          "@context": "https://schema.org",
          "@type": "BreadcrumbList",
          "itemListElement": [
            {
              "@type": "ListItem",
              "name": "稀土掘金",
              "position": 1,
              "item": "https://juejin.cn"
            },
            {
              "@type": "ListItem",
              "name": "前端",
              "position": 2,
              "item": "https://juejin.cn/frontend"
            },
            { "@type": "ListItem", "name": "文章", "position": 3 }
          ]
        }
      ]
    </script>
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/10e5709.js"
      as="script"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/9928f25.js"
      as="script"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/e77ab26.js"
      as="script"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/app.a19468b.css"
      as="style"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/26ba7b3.js"
      as="script"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/layouts/default.58569e9.css"
      as="style"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/d61db58.js"
      as="script"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/60.620b8c3.css"
      as="style"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/33abca8.js"
      as="script"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/221.696c239.css"
      as="style"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/65b1426.js"
      as="script"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/102.9f93b63.css"
      as="style"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/990892a.js"
      as="script"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/214.8de3951.css"
      as="style"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/956677f.js"
      as="script"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/217.adcadde.css"
      as="style"
    />
    <link
      rel="preload"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/24eeb15.js"
      as="script"
    />
    <link
      rel="stylesheet"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/app.a19468b.css"
    />
    <link
      rel="stylesheet"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/layouts/default.58569e9.css"
    />
    <link
      rel="stylesheet"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/60.620b8c3.css"
    />
    <link
      rel="stylesheet"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/221.696c239.css"
    />
    <link
      rel="stylesheet"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/102.9f93b63.css"
    />
    <link
      rel="stylesheet"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/214.8de3951.css"
    />
    <link
      rel="stylesheet"
      href="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/217.adcadde.css"
    />
  </head>

  <body>
    <div data-server-rendered="true" id="__nuxt">
      <div id="__layout">
        <div id="juejin">
          <!---->
          <div class="view-container" data-v-1e8be6f4 data-v-7a561fad>
            <div class="main-header-box" data-v-1e8be6f4>
              <header
                data-fetch-key="0"
                class="main-header main-header unauthorized visible"
                data-v-25e3b163
                data-v-1e8be6f4
              >
                <div class="container" data-v-25e3b163>
                  <a href="/" class="logo" data-v-25e3b163
                    ><img
                      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/e08da34488b114bd4c665ba2fa520a31.svg"
                      alt="稀土掘金"
                      class="logo-img"
                      data-v-25e3b163 />
                    <img
                      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/6c61ae65d1c41ae8221a670fa32d05aa.svg"
                      alt="稀土掘金"
                      class="mobile"
                      data-v-25e3b163
                  /></a>
                  <!---->
                  <!---->
                  <nav role="navigation" class="main-nav" data-v-25e3b163>
                    <ul class="nav-list" data-v-25e3b163>
                      <!---->
                      <li class="main-nav-list" data-v-25e3b163>
                        <div class="phone-show-menu" data-v-25e3b163>
                          <span data-v-25e3b163>首页</span>
                          <svg
                            width="12"
                            height="12"
                            viewBox="0 0 12 12"
                            fill="none"
                            xmlns="http://www.w3.org/2000/svg"
                            class="unfold16-icon"
                            data-v-25e3b163
                            data-v-25e3b163
                          >
                            <path
                              d="M2.45025 4.82431C2.17422 4.49957 2.40501 4.00049 2.83122 4.00049H9.16878C9.59498 4.00049 9.82578 4.49957 9.54975 4.82431L6.38097 8.55229C6.1813 8.78719 5.8187 8.78719 5.61903 8.55229L2.45025 4.82431Z"
                              data-v-25e3b163
                              data-v-25e3b163
                            ></path>
                          </svg>
                        </div>
                        <ul class="phone-hide" data-v-25e3b163>
                          <li
                            class="nav-item link-item route-active"
                            data-v-25e3b163
                          >
                            <a href="/" data-v-25e3b163>首页</a>
                          </li>
                          <li
                            class="nav-item link-item activities"
                            data-v-25e3b163
                          >
                            <a href="/pins" data-v-25e3b163
                              ><span class="text" data-v-25e3b163>
                                沸点
                                <!---->
                              </span></a
                            >
                          </li>
                          <li class="nav-item link-item book" data-v-25e3b163>
                            <a href="/course" data-v-25e3b163>
                              课程
                              <!---->
                            </a>
                          </li>
                          <li class="nav-item link-item" data-v-25e3b163>
                            <a href="/live" data-v-25e3b163>直播</a>
                          </li>
                          <li class="nav-item link-item" data-v-25e3b163>
                            <a href="/events/all" data-v-25e3b163>活动</a>
                          </li>
                          <li class="nav-item link-item" data-v-25e3b163>
                            <a href="/challenge" data-v-25e3b163>
                              竞赛
                              <!---->
                            </a>
                          </li>
                          <nav class="nav-item link-item" data-v-25e3b163>
                            <a
                              href="https://detail.youzan.com/show/goods/newest?kdt_id=104340304"
                              target="_blank"
                              rel="nofollow noopener noreferrer"
                              class="nav-item link-item no-border"
                              data-v-25e3b163
                              ><span data-v-25e3b163>商城</span></a
                            >
                            <!---->
                          </nav>
                          <nav
                            class="nav-item link-item download-icon"
                            data-v-25e3b163
                          >
                            <a
                              href="/app?utm_source=jj_nav"
                              target="_blank"
                              class="download-app no-border"
                              data-v-25e3b163
                            >
                              APP
                            </a>
                            <!---->
                          </nav>
                          <nav
                            class="nav-item link-item extension-icon"
                            data-v-25e3b163
                          >
                            <a
                              href="https://juejin.cn/extension?utm_source=jj_nav"
                              target="_blank"
                              rel="nofollow noopener noreferrer"
                              class="broswer-extension no-border"
                              data-v-25e3b163
                              ><span data-v-25e3b163>插件</span></a
                            >
                          </nav>
                          <!---->
                        </ul>
                      </li>
                      <ul class="right-side-nav" data-v-25e3b163>
                        <li class="search-add" data-v-25e3b163>
                          <ul class="search-add-ul" data-v-25e3b163>
                            <li class="nav-item search" data-v-25e3b163>
                              <form
                                role="search"
                                class="search-form"
                                data-v-25e3b163
                              >
                                <input
                                  type="search"
                                  maxlength="64"
                                  placeholder=""
                                  value=""
                                  class="search-input"
                                  data-v-25e3b163
                                />
                                <div
                                  class="seach-icon-container"
                                  data-v-25e3b163
                                >
                                  <svg
                                    width="18"
                                    height="18"
                                    viewBox="0 0 18 18"
                                    fill="none"
                                    xmlns="http://www.w3.org/2000/svg"
                                    class="search-icon"
                                    data-v-25e3b163
                                    data-v-25e3b163
                                  >
                                    <path
                                      d="M12.4008 12.4008C14.744 10.0577 14.744 6.25871 12.4008 3.91556C10.0577 1.57242 6.25871 1.57242 3.91556 3.91556C1.57242 6.25871 1.57242 10.0577 3.91556 12.4008C6.25871 14.744 10.0577 14.744 12.4008 12.4008ZM12.4008 12.4008L15.5828 15.5828"
                                      stroke-width="1.5"
                                      stroke-linecap="round"
                                      stroke-linejoin="round"
                                      data-v-25e3b163
                                      data-v-25e3b163
                                    ></path>
                                  </svg>
                                </div>
                                <div
                                  class="typehead"
                                  style="display: none"
                                  data-v-25e3b163
                                >
                                  <!---->
                                  <div class="title" data-v-25e3b163>
                                    <span data-v-25e3b163>搜索历史</span>
                                    <span class="clear" data-v-25e3b163>
                                      清空
                                    </span>
                                  </div>
                                  <div class="list" data-v-25e3b163></div>
                                </div>
                              </form>
                            </li>
                            <li
                              class="nav-item add creator-item"
                              data-v-25e3b163
                            >
                              <div
                                class="add-group"
                                data-v-9fa8ab8e
                                data-v-25e3b163
                              >
                                <!---->
                                <button class="add-btn" data-v-9fa8ab8e>
                                  创作者中心
                                </button>
                                <div class="more" data-v-9fa8ab8e>
                                  <svg
                                    width="12"
                                    height="12"
                                    viewBox="0 0 12 12"
                                    fill="none"
                                    xmlns="http://www.w3.org/2000/svg"
                                    class="unfold12-icon"
                                    data-v-9fa8ab8e
                                    data-v-9fa8ab8e
                                  >
                                    <path
                                      d="M2.45025 4.82383C2.17422 4.49908 2.40501 4 2.83122 4H9.16878C9.59499 4 9.82578 4.49908 9.54975 4.82382L6.38097 8.5518C6.1813 8.7867 5.8187 8.7867 5.61903 8.5518L2.45025 4.82383Z"
                                      fill="white"
                                      data-v-9fa8ab8e
                                      data-v-9fa8ab8e
                                    ></path>
                                  </svg>
                                  <div class="more-mask" data-v-9fa8ab8e></div>
                                  <div class="more-list" data-v-9fa8ab8e>
                                    <ul class="menu" data-v-9fa8ab8e>
                                      <li class="item" data-v-9fa8ab8e>
                                        <div
                                          class="icon write-article"
                                          data-v-9fa8ab8e
                                        ></div>
                                        <div class="title" data-v-9fa8ab8e>
                                          写文章
                                        </div>
                                      </li>
                                      <li class="item" data-v-9fa8ab8e>
                                        <div
                                          class="icon issue-points"
                                          data-v-9fa8ab8e
                                        ></div>
                                        <div class="title" data-v-9fa8ab8e>
                                          发沸点
                                        </div>
                                      </li>
                                      <li class="item" data-v-9fa8ab8e>
                                        <div
                                          class="icon write-note"
                                          data-v-9fa8ab8e
                                        ></div>
                                        <div class="title" data-v-9fa8ab8e>
                                          写笔记
                                        </div>
                                      </li>
                                      <li class="item" data-v-9fa8ab8e>
                                        <div
                                          class="icon create-jcode"
                                          data-v-9fa8ab8e
                                        ></div>
                                        <div class="title" data-v-9fa8ab8e>
                                          写代码
                                        </div>
                                      </li>
                                      <li class="item" data-v-9fa8ab8e>
                                        <div
                                          class="icon drafts"
                                          data-v-9fa8ab8e
                                        ></div>
                                        <div class="title" data-v-9fa8ab8e>
                                          草稿箱
                                        </div>
                                      </li>
                                    </ul>
                                    <div class="divider" data-v-9fa8ab8e></div>
                                    <div class="inspiration" data-v-9fa8ab8e>
                                      <div class="info" data-v-9fa8ab8e>
                                        <span class="title" data-v-9fa8ab8e
                                          >创作灵感</span
                                        >
                                        <span class="more-info" data-v-9fa8ab8e>
                                          查看更多
                                          <i
                                            class="icon byte-icon byte-icon--right"
                                            data-v-9fa8ab8e
                                            ><svg
                                              t="1561636167146"
                                              class="icon"
                                              viewBox="0 0 1024 1024"
                                              version="1.1"
                                              xmlns="http://www.w3.org/2000/svg"
                                              p-id="404349"
                                              xmlns:xlink="http://www.w3.org/1999/xlink"
                                            >
                                              <path
                                                d="M630.4 512L283.52 165.12a21.12 21.12 0 0 1 0-30.08l30.08-30.08a21.12 21.12 0 0 1 30.08 0l377.6 376.96a42.24 42.24 0 0 1 0 60.16l-377.6 376.96a21.12 21.12 0 0 1-30.08 0l-30.08-30.08a21.12 21.12 0 0 1 0-30.08z"
                                                p-id="404350"
                                              ></path></svg></i
                                        ></span>
                                      </div>
                                      <div class="list" data-v-9fa8ab8e>
                                        <div
                                          class="item"
                                          data-v-3ff8f708
                                          data-v-9fa8ab8e
                                        >
                                          <div
                                            class="xitu-skeleton xitu-skeleton-animated"
                                            data-v-3ff8f708
                                          >
                                            <div
                                              class="xitu-skeleton-item"
                                              data-v-3ff8f708
                                            >
                                              <!---->
                                              <div
                                                class="xitu-skeleton-content"
                                                data-v-3ff8f708
                                              >
                                                <div
                                                  class="xitu-skeleton-line"
                                                  data-v-3ff8f708
                                                ></div>
                                                <div
                                                  class="xitu-skeleton-line"
                                                  data-v-3ff8f708
                                                ></div>
                                                <div
                                                  class="xitu-skeleton-line"
                                                  data-v-3ff8f708
                                                ></div>
                                              </div>
                                            </div>
                                          </div>
                                        </div>
                                      </div>
                                    </div>
                                  </div>
                                </div>
                                <!---->
                              </div>
                            </li>
                          </ul>
                        </li>
                        <!---->
                        <li class="nav-item vip-entry" data-v-25e3b163>
                          <div class="vip-title" data-v-25e3b163>
                            <div class="vip-entry-img" data-v-25e3b163>
                              <img
                                src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/24127194d5b158d7eaf8f09a256c5d01.svg"
                                alt="vip"
                                class="vip-img"
                                data-v-25e3b163
                              />
                              <!---->
                            </div>
                            <div class="vip-words" data-v-25e3b163>会员</div>
                          </div>
                        </li>
                        <!---->
                        <!---->
                        <!---->
                        <li class="nav-item auth" data-v-25e3b163>
                          <div class="login-button-wrap" data-v-25e3b163>
                            <button class="login-button" data-v-25e3b163>
                              登录
                              <!---->
                            </button>
                            <!---->
                          </div>
                        </li>
                      </ul>
                    </ul>
                  </nav>
                </div>
                <!---->
              </header>
            </div>
            <main
              class="container main-container"
              style="max-width: 1140px"
              data-v-1e8be6f4
            >
              <div class="view column-view" data-v-1e8be6f4 data-v-7a561fad>
                <div
                  class="main-area article-area"
                  data-v-1e8be6f4
                  data-v-7a561fad
                >
                  <article
                    itemscope="itemscope"
                    itemtype="http://schema.org/Article"
                    data-entry-id="6950084496515399717"
                    data-draft-id="6940043781823528974"
                    data-original-type="0"
                    class="article"
                    data-v-7a561fad
                  >
                    <!---->
                    <meta
                      itemprop="headline"
                      content="Vue 源码解读（2）—— Vue 初始化过程"
                    />
                    <meta
                      itemprop="keywords"
                      content="JavaScript,Vue.js,前端"
                    />
                    <meta
                      itemprop="datePublished"
                      content="2021-04-12T01:58:21.000Z"
                    />
                    <meta
                      itemprop="image"
                      content="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-assets/icon/icon-128.png~tplv-t2oaga2asx-image.image"
                    />
                    <div
                      itemprop="author"
                      itemscope="itemscope"
                      itemtype="http://schema.org/Person"
                    >
                      <meta itemprop="name" content="李永宁" />
                      <meta
                        itemprop="url"
                        content="https://juejin.cn/user/1028798616461326"
                      />
                    </div>
                    <div
                      itemprop="publisher"
                      itemscope="itemscope"
                      itemtype="http://schema.org/Organization"
                    >
                      <meta itemprop="name" content="掘金" />
                      <div
                        itemprop="logo"
                        itemscope="itemscope"
                        itemtype="https://schema.org/ImageObject"
                      >
                        <meta
                          itemprop="url"
                          content="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-assets/icon/icon-white-180.png~tplv-t2oaga2asx-image.image"
                        />
                        <meta itemprop="width" content="180" />
                        <meta itemprop="height" content="180" />
                      </div>
                    </div>
                    <h1 class="article-title" data-v-7a561fad>
                      Vue 源码解读（2）—— Vue 初始化过程
                      <!---->
                    </h1>
                    <div class="author-info-block" data-v-7a561fad>
                      <a
                        href="/user/1028798616461326"
                        target="_blank"
                        rel=""
                        class="avatar-link"
                        data-v-7a561fad
                        ><img
                          loading="eager"
                          src="https://p3-passport.byteimg.com/img/user-avatar/ecfb3bbd73753344105b06067757a70a~100x100.image"
                          alt=""
                          class="lazy avatar avatar"
                          data-v-248050e4
                          data-v-0b45085c
                          data-v-7a561fad
                      /></a>
                      <div class="author-info-box" data-v-7a561fad>
                        <div class="author-name" data-v-7a561fad>
                          <a
                            href="/user/1028798616461326"
                            target="_blank"
                            rel=""
                            class="username username ellipsis"
                            data-v-2b2ca9ee
                            data-v-7a561fad
                            ><span
                              class="name"
                              style="max-width: 128px"
                              data-v-2b2ca9ee
                            >
                              李永宁
                            </span>
                            <span
                              blank="true"
                              class="rank"
                              data-v-3c1a13dc
                              data-v-2b2ca9ee
                              ><img
                                src=""
                                alt="lv-5"
                                title="创作等级"
                                class="lazy"
                                style="aspect-ratio: NaN"
                                data-v-248050e4
                                data-v-3c1a13dc
                            /></span>
                            <!---->
                            <!---->
                          </a>
                          <!---->
                        </div>
                        <div class="meta-box" data-v-7a561fad>
                          <time
                            datetime="2021-04-12T01:58:21.000Z"
                            title="Mon Apr 12 2021 09:58:21 GMT+0800 (China Standard Time)"
                            class="time"
                            data-v-7a561fad
                          >
                            2021年04月12日 09:58
                          </time>
                          <span
                            class="views-count"
                            style="display: none"
                            data-v-7a561fad
                          >
                            ·  阅读 38400
                          </span>
                          <!---->
                        </div>
                      </div>
                      <!---->
                    </div>
                    <!---->
                    <img
                      loading="eager"
                      src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4cf0e7b553704152a23879301ed0c58c~tplv-k3u1fbpfcp-zoom-crop-mark:1512:1512:1512:851.image"
                      alt="Vue 源码解读（2）—— Vue 初始化过程"
                      class="lazy article-hero"
                      data-v-248050e4
                      data-v-7a561fad
                    />
                    <!---->
                    <!---->
                    <div
                      itemprop="articleBody"
                      class="article-content"
                      data-v-7a561fad
                    >
                      <div class="markdown-body cache">
                        <html>
                          <head>
                            <style>
                              @charset "UTF-8";

                              .markdown-body {
                                word-break: break-word;
                                line-height: 1.75;
                                font-weight: 400;
                                font-size: 14px;
                                overflow-x: hidden;
                                color: var(--cyanosis-base-color);
                                transition: color 0.35s;
                                --cyanosis-base-color: #353535;
                                --cyanosis-title-color: #005bb7;
                                --cyanosis-strong-color: #2196f3;
                                --cyanosis-em-color: #4fc3f7;
                                --cyanosis-del-color: #ccc;
                                --cyanosis-link-color: #3da8f5;
                                --cyanosis-linkh-color: #007fff;
                                --cyanosis-border-color: #bedcff;
                                --cyanosis-border-color-2: #ececec;
                                --cyanosis-bg-color: #fff;
                                --cyanosis-blockquote-color: #8c8c8c;
                                --cyanosis-blockquote-bg-color: #f0fdff;
                                --cyanosis-code-color: #c2185b;
                                --cyanosis-code-bg-color: #fff4f4;
                                --cyanosis-code-pre-color: #f8f8f8;
                                --cyanosis-table-border-color: #c3e0fd;
                                --cyanosis-table-th-color: #dff0ff;
                                --cyanosis-table-tht-color: #005bb7;
                                --cyanosis-table-tr-nc-color: #f7fbff;
                                --cyanosis-table-trh-color: #e0edf7;
                                --cyanosis-slct-title-color: #005bb7;
                                --cyanosis-slct-titlebg-color: rgba(
                                  175,
                                  207,
                                  247,
                                  0.25
                                );
                                --cyanosis-slct-text-color: #c80000;
                                --cyanosis-slct-bg-color: rgba(
                                  175,
                                  207,
                                  247,
                                  0.25
                                );
                                --cyanosis-slct-del-color: #999;
                                --cyanosis-slct-elbg-color: #e8ebec;
                                --cyanosis-slct-codebg-color: #ffeaeb;
                                --cyanosis-slct-prebg-color: rgba(
                                  160,
                                  200,
                                  255,
                                  0.25
                                );
                              }

                              .markdown-body.__dark {
                                --cyanosis-base-color: #cacaca;
                                --cyanosis-title-color: #ddd;
                                --cyanosis-strong-color: #fe9900;
                                --cyanosis-em-color: #ffd28e;
                                --cyanosis-del-color: #ccc;
                                --cyanosis-link-color: #ffb648;
                                --cyanosis-linkh-color: #fe9900;
                                --cyanosis-border-color: #ffe3ba;
                                --cyanosis-border-color-2: #ffcb7b;
                                --cyanosis-bg-color: #2f2f2f;
                                --cyanosis-blockquote-color: #c7c7c7;
                                --cyanosis-blockquote-bg-color: rgba(
                                  255,
                                  199,
                                  116,
                                  0.1
                                );
                                --cyanosis-code-color: #000;
                                --cyanosis-code-bg-color: #ffcb7b;
                                --cyanosis-code-pre-color: rgba(
                                  255,
                                  227,
                                  185,
                                  0.5
                                );
                                --cyanosis-table-border-color: #fe9900;
                                --cyanosis-table-th-color: #ffb648;
                                --cyanosis-table-tht-color: #000;
                                --cyanosis-table-tr-nc-color: #6d5736;
                                --cyanosis-table-trh-color: #947443;
                                --cyanosis-slct-title-color: #000;
                                --cyanosis-slct-titlebg-color: #fe9900;
                                --cyanosis-slct-text-color: #00c888;
                                --cyanosis-slct-bg-color: rgba(
                                  175,
                                  207,
                                  247,
                                  0.25
                                );
                                --cyanosis-slct-del-color: #999;
                                --cyanosis-slct-elbg-color: #000;
                                --cyanosis-slct-codebg-color: #ffcb7b;
                                --cyanosis-slct-prebg-color: rgba(
                                  160,
                                  200,
                                  255,
                                  0.25
                                );
                              }

                              .markdown-body h1 {
                                padding-bottom: 4px;
                                font-size: 30px;
                              }

                              .markdown-body h1,
                              .markdown-body h2 {
                                margin-top: 36px;
                                margin-bottom: 10px;
                                line-height: 1.5;
                                color: var(--cyanosis-title-color);
                                transition: color 0.35s;
                              }

                              .markdown-body h2 {
                                position: relative;
                                padding-left: 10px;
                                padding-right: 10px;
                                padding-bottom: 10px;
                                font-size: 24px;
                                border-bottom: 1px solid
                                  var(--cyanosis-border-color-2);
                              }

                              .markdown-body h2:before {
                                content: "「";
                                position: absolute;
                                top: -6px;
                                left: -14px;
                              }

                              .markdown-body h2:after {
                                content: "」";
                                position: relative;
                                top: 6px;
                                right: auto;
                              }

                              .markdown-body h3 {
                                position: relative;
                                padding-bottom: 0;
                                margin-top: 30px;
                                margin-bottom: 10px;
                                font-size: 20px;
                                line-height: 1.5;
                                color: var(--cyanosis-title-color);
                                padding-left: 6px;
                                transition: color 0.35s;
                              }

                              .markdown-body h3:before {
                                content: "»";
                                padding-right: 6px;
                                color: var(--cyanosis-strong-color);
                              }

                              .markdown-body h4 {
                                margin-top: 24px;
                                font-size: 16px;
                              }

                              .markdown-body h4,
                              .markdown-body h5 {
                                padding-bottom: 0;
                                margin-bottom: 10px;
                                line-height: 1.5;
                                color: var(--cyanosis-title-color);
                                padding-left: 6px;
                                transition: color 0.35s;
                              }

                              .markdown-body h5 {
                                margin-top: 18px;
                                font-size: 14px;
                              }

                              .markdown-body h6 {
                                padding-bottom: 0;
                                margin-top: 12px;
                                margin-bottom: 10px;
                                font-size: 12px;
                                line-height: 1.5;
                                color: var(--cyanosis-title-color);
                                padding-left: 6px;
                                transition: color 0.35s;
                              }

                              .markdown-body p {
                                line-height: inherit;
                                margin-top: 16px;
                                margin-bottom: 16px;
                              }

                              .markdown-body img {
                                max-width: 100%;
                              }

                              .markdown-body hr {
                                position: relative;
                                width: 98%;
                                height: 1px;
                                margin-top: 32px;
                                margin-bottom: 32px;
                                background-image: linear-gradient(
                                  90deg,
                                  var(--cyanosis-link-color),
                                  rgba(255, 0, 0, 0.3),
                                  hsla(0, 0%, 100%, 0.1),
                                  rgba(255, 0, 0, 0.3),
                                  var(--cyanosis-link-color)
                                );
                                border-width: 0;
                                overflow: visible;
                              }

                              .markdown-body hr:after {
                                content: "";
                                position: absolute;
                                margin: auto;
                                left: 0;
                                right: 0;
                                bottom: 0;
                                top: 0;
                                display: inline-block;
                                width: 60px;
                                height: 20px;
                                background-color: var(--cyanosis-bg-color);
                                background-image: url();
                                background-repeat: no-repeat;
                                background-size: auto 100%;
                                background-position-x: center;
                                transition: background-color 0.5s;
                              }

                              .markdown-body code {
                                padding: 0.065em 0.4em;
                                font-size: 0.87em;
                                color: var(--cyanosis-code-color);
                                word-break: break-word;
                                overflow-x: auto;
                                background-color: var(--cyanosis-code-bg-color);
                                border-radius: 2px;
                              }

                              .markdown-body code,
                              .markdown-body pre {
                                font-family: Menlo, Monaco, Consolas,
                                  Courier New, monospace;
                              }

                              .markdown-body pre {
                                overflow: auto;
                                position: relative;
                                line-height: 1.75;
                              }

                              .markdown-body pre > code {
                                display: block;
                                padding: 16px 12px;
                                margin: 0;
                                font-size: 12px;
                                color: #333;
                                word-break: normal;
                                overflow-x: auto;
                                background: var(--cyanosis-code-pre-color);
                              }

                              .markdown-body pre > code::-webkit-scrollbar {
                                width: 4px;
                                height: 4px;
                              }

                              .markdown-body
                                pre
                                > code::-webkit-scrollbar-track {
                                background-color: var(--cyanosis-border-color);
                              }

                              .markdown-body
                                pre
                                > code::-webkit-scrollbar-thumb {
                                background-color: var(--cyanosis-strong-color);
                                border-radius: 10px;
                              }

                              .markdown-body a {
                                position: relative;
                                text-decoration: none;
                                color: var(--cyanosis-link-color);
                                border-bottom: 1px solid
                                  var(--cyanosis-border-color);
                              }

                              .markdown-body a:hover {
                                border-bottom-color: var(
                                  --cyanosis-linkh-color
                                );
                              }

                              .markdown-body a:active,
                              .markdown-body a:hover {
                                color: var(--cyanosis-linkh-color);
                              }

                              .markdown-body a:after {
                                position: absolute;
                                content: "";
                                top: 100%;
                                left: 0;
                                width: 100%;
                                opacity: 0;
                                border-bottom: 1px solid
                                  var(--cyanosis-border-color);
                                transition: top 0.3s, opacity 0.3s;
                                transform: translateZ(0);
                              }

                              .markdown-body a:hover:after {
                                top: 0;
                                opacity: 1;
                                border-bottom-color: var(
                                  --cyanosis-linkh-color
                                );
                              }

                              .markdown-body table {
                                display: inline-block !important;
                                font-size: 12px;
                                width: auto;
                                max-width: 100%;
                                overflow: auto;
                                border: 1px solid
                                  var(--cyanosis-table-border-color);
                                border-spacing: 0;
                                border-collapse: collapse;
                              }

                              .markdown-body table thead {
                                color: #000;
                                text-align: left;
                                font-size: 14px;
                                background: #f6f6f6;
                              }

                              .markdown-body table tr:nth-child(2n) {
                                background-color: var(
                                  --cyanosis-table-tr-nc-color
                                );
                              }

                              .markdown-body table tr:hover {
                                background-color: var(
                                  --cyanosis-table-trh-color
                                );
                              }

                              .markdown-body table td,
                              .markdown-body table th {
                                padding: 12px 8px;
                                line-height: 24px;
                                border: 1px solid
                                  var(--cyanosis-table-border-color);
                              }

                              .markdown-body table th {
                                color: var(--cyanosis-table-tht-color);
                                background-color: var(
                                  --cyanosis-table-th-color
                                );
                              }

                              .markdown-body table td {
                                min-width: 120px;
                              }

                              .markdown-body blockquote {
                                color: var(--cyanosis-blockquote-color);
                                border-left: 4px solid
                                  var(--cyanosis-strong-color);
                                background-color: var(
                                  --cyanosis-blockquote-bg-color
                                );
                                padding: 1px 20px;
                                margin: 22px 0;
                                transition: color 0.35s;
                              }

                              .markdown-body blockquote:after {
                                display: block;
                                content: "";
                              }

                              .markdown-body blockquote > p {
                                margin: 10px 0;
                              }

                              .markdown-body b,
                              .markdown-body blockquote > b,
                              .markdown-body blockquote > strong,
                              .markdown-body strong {
                                color: var(--cyanosis-strong-color);
                              }

                              .markdown-body em,
                              .markdown-body i {
                                color: var(--cyanosis-em-color);
                              }

                              .markdown-body del {
                                color: var(--cyanosis-del-color);
                              }

                              .markdown-body ol,
                              .markdown-body ul {
                                padding-left: 28px;
                              }

                              .markdown-body ol li,
                              .markdown-body ul li {
                                margin-bottom: 0;
                                list-style: inherit;
                              }

                              .markdown-body ol li .task-list-item,
                              .markdown-body ul li .task-list-item {
                                list-style: none;
                              }

                              .markdown-body ol li .task-list-item ol,
                              .markdown-body ol li .task-list-item ul,
                              .markdown-body ul li .task-list-item ol,
                              .markdown-body ul li .task-list-item ul {
                                margin-top: 0;
                              }

                              .markdown-body ol ol,
                              .markdown-body ol ul,
                              .markdown-body ul ol,
                              .markdown-body ul ul {
                                margin-top: 4px;
                              }

                              .markdown-body ol li {
                                padding-left: 6px;
                              }

                              .markdown-body details > summary {
                                outline: none;
                                color: var(--cyanosis-title-color);
                                font-size: 20px;
                                font-weight: bolder;
                                border-bottom: 1px solid
                                  var(--cyanosis-border-color);
                                cursor: pointer;
                              }

                              .markdown-body details > p {
                                padding: 10px 20px;
                                margin: 10px 0 0;
                                color: #666;
                                background-color: var(
                                  --cyanosis-blockquote-bg-color
                                );
                                border: 2px dashed var(--cyanosis-strong-color);
                              }

                              .markdown-body h1::selection,
                              .markdown-body h2::selection,
                              .markdown-body h3::selection,
                              .markdown-body h4::selection,
                              .markdown-body h5::selection,
                              .markdown-body h6::selection {
                                color: var(--cyanosis-slct-title-color);
                                background-color: var(
                                  --cyanosis-slct-titlebg-color
                                );
                              }

                              .markdown-body ol li::selection,
                              .markdown-body p::selection,
                              .markdown-body ul li::selection {
                                color: var(--cyanosis-slct-text-color);
                                background-color: var(--cyanosis-slct-bg-color);
                              }

                              .markdown-body a::selection,
                              .markdown-body b::selection,
                              .markdown-body em::selection,
                              .markdown-body i::selection,
                              .markdown-body strong::selection {
                                background-color: var(
                                  --cyanosis-slct-elbg-color
                                );
                              }

                              .markdown-body del::selection {
                                color: var(--cyanosis-slct-del-color);
                                background-color: var(
                                  --cyanosis-slct-elbg-color
                                );
                              }

                              .markdown-body table thead th::selection {
                                background-color: transparent;
                              }

                              .markdown-body table tbody td::selection {
                                background-color: var(--cyanosis-slct-bg-color);
                              }

                              .markdown-body code::selection {
                                background-color: var(
                                  --cyanosis-slct-codebg-color
                                );
                              }

                              .markdown-body pre > code::selection {
                                background-color: var(
                                  --cyanosis-slct-prebg-color
                                );
                              }

                              .markdown-body .contains-task-list {
                                padding-left: 14px;
                                list-style: none;
                              }

                              .markdown-body
                                .contains-task-list
                                input[type="checkbox"] {
                                position: relative;
                              }

                              .markdown-body
                                .contains-task-list
                                input[type="checkbox"]:before {
                                content: "";
                                position: absolute;
                                top: 0;
                                left: 0;
                                right: 0;
                                bottom: 0;
                                width: inherit;
                                height: inherit;
                                background: #f0f8ff;
                                border: 1px solid #add6ff;
                                border-radius: 2px;
                                box-sizing: border-box;
                                z-index: 1;
                              }

                              .markdown-body
                                .contains-task-list
                                input[type="checkbox"]:checked:after {
                                content: "✓";
                                position: absolute;
                                top: -12px;
                                left: 0;
                                right: 0;
                                bottom: 0;
                                width: 0;
                                height: 0;
                                color: #f55;
                                font-size: 20px;
                                font-weight: 700;
                                z-index: 2;
                              }

                              @media (max-width: 720px) {
                                .markdown-body h1 {
                                  font-size: 24px;
                                }

                                .markdown-body h2 {
                                  font-size: 20px;
                                }

                                .markdown-body h3 {
                                  font-size: 18px;
                                }
                              }
                            </style>
                            <style
                              data-highlight=""
                              data-highlight-key="androidstudio"
                            >
                              .markdown-body pre,
                              .markdown-body pre > code.hljs {
                                color: #a9b7c6;
                                background: #282b2e;
                              }

                              .hljs-bullet,
                              .hljs-literal,
                              .hljs-number,
                              .hljs-symbol {
                                color: #6897bb;
                              }

                              .hljs-deletion,
                              .hljs-keyword,
                              .hljs-selector-tag {
                                color: #cc7832;
                              }

                              .hljs-link,
                              .hljs-template-variable,
                              .hljs-variable {
                                color: #629755;
                              }

                              .hljs-comment,
                              .hljs-quote {
                                color: grey;
                              }

                              .hljs-meta {
                                color: #bbb529;
                              }

                              .hljs-addition,
                              .hljs-attribute,
                              .hljs-string {
                                color: #6a8759;
                              }

                              .hljs-section,
                              .hljs-title,
                              .hljs-type {
                                color: #ffc66d;
                              }

                              .hljs-name,
                              .hljs-selector-class,
                              .hljs-selector-id {
                                color: #e8bf6a;
                              }

                              .hljs-emphasis {
                                font-style: italic;
                              }

                              .hljs-strong {
                                font-weight: 700;
                              }
                            </style>
                          </head>

                          <body>
                            <p>
                              <strong
                                >当学习成为了习惯，知识也就变成了常识。</strong
                              >
                              感谢各位的
                              <strong>点赞</strong
                              >、<strong>收藏</strong>和<strong>评论</strong>。
                            </p>
                            <base
                              href="https://juejin.cn/post/6950084496515399717"
                            />
                            <p>
                              新视频和文章会第一时间在微信公众号发送，欢迎关注：<a
                                href="https://link.juejin.cn?target=https%3A%2F%2Fgitee.com%2Fliyongning%2Ftypora-image-bed%2Fraw%2Fmaster%2F202202171742614.jpg"
                                target="_blank"
                                title="https://gitee.com/liyongning/typora-image-bed/raw/master/202202171742614.jpg"
                                ref="nofollow noopener noreferrer"
                                >李永宁lyn</a
                              >
                            </p>
                            <p>
                              文章已收录到
                              <a
                                href="https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fliyongning%2Fblog"
                                target="_blank"
                                title="https://github.com/liyongning/blog"
                                ref="nofollow noopener noreferrer"
                                >github</a
                              >，欢迎 Watch 和 Star。
                            </p>
                            <h1 data-id="heading-0">目标</h1>
                            <p>
                              深入理解 Vue 的初始化过程，再也不怕
                              <strong>面试官</strong> 的那道面试题：<code
                                >new Vue(options)</code
                              >
                              发生了什么？
                            </p>
                            <h1 data-id="heading-1">找入口</h1>
                            <p>
                              想知道
                              <code>new Vue(options)</code>
                              都做了什么，就得先找到 Vue
                              的构造函数是在哪声明的，有两个办法：
                            </p>
                            <ul>
                              <li>
                                <p>
                                  从 rollup
                                  配置文件中找到编译的入口，然后一步步找到 Vue
                                  构造函数，这种方式 <strong>费劲</strong>
                                </p>
                              </li>
                              <li>
                                <p>
                                  通过编写示例代码，然后打断点的方式，一步到位，<strong
                                    >简单</strong
                                  >
                                </p>
                              </li>
                            </ul>
                            <p>
                              我们就采用第二种方式，写示例，打断点，一步到位。
                            </p>
                            <ul>
                              <li>
                                在 <code>/examples</code> 目录下增加一个示例文件
                                ——
                                <code>test.html</code>，在文件中添加如下内容：
                              </li>
                            </ul>
                            <pre><code class="hljs language-html copyable" lang="html"><span class="hljs-meta">&#x3C;!DOCTYPE <span class="hljs-keyword">html</span>></span>
<span class="hljs-tag">&#x3C;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>
<span class="hljs-tag">&#x3C;<span class="hljs-name">head</span>></span>
  <span class="hljs-tag">&#x3C;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>
  <span class="hljs-tag">&#x3C;<span class="hljs-name">title</span>></span>Vue 源码解读<span class="hljs-tag">&#x3C;/<span class="hljs-name">title</span>></span>
<span class="hljs-tag">&#x3C;/<span class="hljs-name">head</span>></span>
<span class="hljs-tag">&#x3C;<span class="hljs-name">body</span>></span>
  <span class="hljs-tag">&#x3C;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>></span>
    {{ msg }}
  <span class="hljs-tag">&#x3C;/<span class="hljs-name">div</span>></span>
  <span class="hljs-tag">&#x3C;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"../dist/vue.js"</span>></span><span class="hljs-tag">&#x3C;/<span class="hljs-name">script</span>></span>
  <span class="hljs-tag">&#x3C;<span class="hljs-name">script</span>></span><span class="javascript">
    <span class="hljs-keyword">debugger</span>
    <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vue</span>({
      <span class="hljs-attr">el</span>: <span class="hljs-string">'#app'</span>,
      <span class="hljs-attr">data</span>: {
        <span class="hljs-attr">msg</span>: <span class="hljs-string">'hello vue'</span>
      }
    })
  </span><span class="hljs-tag">&#x3C;/<span class="hljs-name">script</span>></span>
<span class="hljs-tag">&#x3C;/<span class="hljs-name">body</span>></span>
<span class="hljs-tag">&#x3C;/<span class="hljs-name">html</span>></span>
<span class="copy-code-btn">复制代码</span></code></pre>
                            <ul>
                              <li>
                                在浏览器中打开控制台，然后打开
                                <code>test.html</code
                                >，则会进入断点调试，然后找到 Vue
                                构造函数所在的文件
                              </li>
                            </ul>
                            <p>
                              <img
                                src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d839ea6f3e5d4adcaf1ea9a8f6ff1a70~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.image"
                                alt="Mar-26-2021 08-30-52.gif"
                                loading="lazy"
                              />
                            </p>
                            <p>
                              得到 Vue 构造函数在
                              <code>/src/core/instance/index.js</code>
                              文件中，接下来正式开始源码阅读，带着目标去阅读。
                            </p>
                            <blockquote>
                              <p>
                                在阅读过程中如遇到看不明白的地方，可通过编写示例代码，然后使用浏览器的调试功能进行一步步调试，配合理解，如果还是理解不了，就做个备注继续向后看，也许你看到其它地方，就突然明白这个地方在做什么，或者回头再来看，就会懂了，源码这个东西，一定要多看，要想精通，一遍两遍肯定是不够的
                              </p>
                            </blockquote>
                            <h1 data-id="heading-2">
                              源码解读 —— Vue 初始化过程
                            </h1>
                            <h2 data-id="heading-3">Vue</h2>
                            <blockquote>
                              <p>/src/core/instance/index.js</p>
                            </blockquote>
                            <pre><code class="hljs language-javascript copyable" lang="javascript"><span class="hljs-keyword">import</span> { initMixin } <span class="hljs-keyword">from</span> <span class="hljs-string">'./init'</span>

<span class="hljs-comment">// Vue 构造函数</span>
<span class="hljs-keyword">function</span> <span class="hljs-title function_">Vue</span> (options) {
  <span class="hljs-comment">// 调用 Vue.prototype._init 方法，该方法是在 initMixin 中定义的</span>
  <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_init</span>(options)
}

<span class="hljs-comment">// 定义 Vue.prototype._init 方法</span>
<span class="hljs-title function_">initMixin</span>(<span class="hljs-title class_">Vue</span>)

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">Vue</span>
<span class="copy-code-btn">复制代码</span></code></pre>
                            <h2 data-id="heading-4">Vue.prototype._init</h2>
                            <blockquote>
                              <p>/src/core/instance/init.js</p>
                            </blockquote>
                            <pre><code class="hljs language-javascript copyable" lang="javascript"><span class="hljs-comment">/**
 * 定义 Vue.prototype._init 方法 
 * <span class="hljs-doctag">@param</span> {<span class="hljs-type">*</span>} Vue Vue 构造函数
 */</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">initMixin</span> (<span class="hljs-title class_">Vue</span>: <span class="hljs-title class_">Class</span>&#x3C;<span class="hljs-title class_">Component</span>>) {
  <span class="hljs-comment">// 负责 Vue 的初始化过程</span>
  <span class="hljs-title class_">Vue</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">_init</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">options?: <span class="hljs-built_in">Object</span></span>) {
    <span class="hljs-comment">// vue 实例</span>
    <span class="hljs-keyword">const</span> <span class="hljs-attr">vm</span>: <span class="hljs-title class_">Component</span> = <span class="hljs-variable language_">this</span>
    <span class="hljs-comment">// 每个 vue 实例都有一个 _uid，并且是依次递增的</span>
    vm.<span class="hljs-property">_uid</span> = uid++

    <span class="hljs-comment">// a flag to avoid this being observed</span>
    vm.<span class="hljs-property">_isVue</span> = <span class="hljs-literal">true</span>
    <span class="hljs-comment">// 处理组件配置项</span>
    <span class="hljs-keyword">if</span> (options &#x26;&#x26; options.<span class="hljs-property">_isComponent</span>) {
      <span class="hljs-comment">/**
       * 每个子组件初始化时走这里，这里只做了一些性能优化
       * 将组件配置对象上的一些深层次属性放到 vm.$options 选项中，以提高代码的执行效率
       */</span>
      <span class="hljs-title function_">initInternalComponent</span>(vm, options)
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-comment">/**
       * 初始化根组件时走这里，合并 Vue 的全局配置到根组件的局部配置，比如 Vue.component 注册的全局组件会合并到 根实例的 components 选项中
       * 至于每个子组件的选项合并则发生在两个地方：
       *   1、Vue.component 方法注册的全局组件在注册时做了选项合并
       *   2、{ components: { xx } } 方式注册的局部组件在执行编译器生成的 render 函数时做了选项合并，包括根组件中的 components 配置
       */</span>
      vm.<span class="hljs-property">$options</span> = <span class="hljs-title function_">mergeOptions</span>(
        <span class="hljs-title function_">resolveConstructorOptions</span>(vm.<span class="hljs-property">constructor</span>),
        options || {},
        vm
      )
    }
    <span class="hljs-comment">/* istanbul ignore else */</span>
    <span class="hljs-keyword">if</span> (process.<span class="hljs-property">env</span>.<span class="hljs-property">NODE_ENV</span> !== <span class="hljs-string">'production'</span>) {
      <span class="hljs-comment">// 设置代理，将 vm 实例上的属性代理到 vm._renderProxy</span>
      <span class="hljs-title function_">initProxy</span>(vm)
    } <span class="hljs-keyword">else</span> {
      vm.<span class="hljs-property">_renderProxy</span> = vm
    }
    <span class="hljs-comment">// expose real self</span>
    vm.<span class="hljs-property">_self</span> = vm
    <span class="hljs-comment">// 初始化组件实例关系属性，比如 $parent、$children、$root、$refs 等</span>
    <span class="hljs-title function_">initLifecycle</span>(vm)
    <span class="hljs-comment">/**
     * 初始化自定义事件，这里需要注意一点，所以我们在 &#x3C;comp <span class="hljs-doctag">@click</span>="handleClick" /> 上注册的事件，监听者不是父组件，
     * 而是子组件本身，也就是说事件的派发和监听者都是子组件本身，和父组件无关
     */</span>
    <span class="hljs-title function_">initEvents</span>(vm)
    <span class="hljs-comment">// 解析组件的插槽信息，得到 vm.$slot，处理渲染函数，得到 vm.$createElement 方法，即 h 函数</span>
    <span class="hljs-title function_">initRender</span>(vm)
    <span class="hljs-comment">// 调用 beforeCreate 钩子函数</span>
    <span class="hljs-title function_">callHook</span>(vm, <span class="hljs-string">'beforeCreate'</span>)
    <span class="hljs-comment">// 初始化组件的 inject 配置项，得到 result[key] = val 形式的配置对象，然后对结果数据进行响应式处理，并代理每个 key 到 vm 实例</span>
    <span class="hljs-title function_">initInjections</span>(vm) <span class="hljs-comment">// resolve injections before data/props</span>
    <span class="hljs-comment">// 数据响应式的重点，处理 props、methods、data、computed、watch</span>
    <span class="hljs-title function_">initState</span>(vm)
    <span class="hljs-comment">// 解析组件配置项上的 provide 对象，将其挂载到 vm._provided 属性上</span>
    <span class="hljs-title function_">initProvide</span>(vm) <span class="hljs-comment">// resolve provide after data/props</span>
    <span class="hljs-comment">// 调用 created 钩子函数</span>
    <span class="hljs-title function_">callHook</span>(vm, <span class="hljs-string">'created'</span>)

    <span class="hljs-comment">// 如果发现配置项上有 el 选项，则自动调用 $mount 方法，也就是说有了 el 选项，就不需要再手动调用 $mount，反之，没有 el 则必须手动调用 $mount</span>
    <span class="hljs-keyword">if</span> (vm.<span class="hljs-property">$options</span>.<span class="hljs-property">el</span>) {
      <span class="hljs-comment">// 调用 $mount 方法，进入挂载阶段</span>
      vm.$mount(vm.<span class="hljs-property">$options</span>.<span class="hljs-property">el</span>)
    }
  }
}

<span class="copy-code-btn">复制代码</span></code></pre>
                            <h2 data-id="heading-5">
                              resolveConstructorOptions
                            </h2>
                            <blockquote>
                              <p>/src/core/instance/init.js</p>
                            </blockquote>
                            <pre><code class="hljs language-javascript copyable" lang="javascript"><span class="hljs-comment">/**
 * 从组件构造函数中解析配置对象 options，并合并基类选项
 * <span class="hljs-doctag">@param</span> {<span class="hljs-type">*</span>} Ctor 
 * <span class="hljs-doctag">@returns</span> 
 */</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">resolveConstructorOptions</span> (<span class="hljs-title class_">Ctor</span>: <span class="hljs-title class_">Class</span>&#x3C;<span class="hljs-title class_">Component</span>>) {
  <span class="hljs-comment">// 配置项目</span>
  <span class="hljs-keyword">let</span> options = <span class="hljs-title class_">Ctor</span>.<span class="hljs-property">options</span>
  <span class="hljs-keyword">if</span> (<span class="hljs-title class_">Ctor</span>.<span class="hljs-property">super</span>) {
    <span class="hljs-comment">// 存在基类，递归解析基类构造函数的选项</span>
    <span class="hljs-keyword">const</span> superOptions = <span class="hljs-title function_">resolveConstructorOptions</span>(<span class="hljs-title class_">Ctor</span>.<span class="hljs-property">super</span>)
    <span class="hljs-keyword">const</span> cachedSuperOptions = <span class="hljs-title class_">Ctor</span>.<span class="hljs-property">superOptions</span>
    <span class="hljs-keyword">if</span> (superOptions !== cachedSuperOptions) {
      <span class="hljs-comment">// 说明基类构造函数选项已经发生改变，需要重新设置</span>
      <span class="hljs-title class_">Ctor</span>.<span class="hljs-property">superOptions</span> = superOptions
      <span class="hljs-comment">// 检查 Ctor.options 上是否有任何后期修改/附加的选项（＃4976）</span>
      <span class="hljs-keyword">const</span> modifiedOptions = <span class="hljs-title function_">resolveModifiedOptions</span>(<span class="hljs-title class_">Ctor</span>)
      <span class="hljs-comment">// 如果存在被修改或增加的选项，则合并两个选项</span>
      <span class="hljs-keyword">if</span> (modifiedOptions) {
        <span class="hljs-title function_">extend</span>(<span class="hljs-title class_">Ctor</span>.<span class="hljs-property">extendOptions</span>, modifiedOptions)
      }
      <span class="hljs-comment">// 选项合并，将合并结果赋值为 Ctor.options</span>
      options = <span class="hljs-title class_">Ctor</span>.<span class="hljs-property">options</span> = <span class="hljs-title function_">mergeOptions</span>(superOptions, <span class="hljs-title class_">Ctor</span>.<span class="hljs-property">extendOptions</span>)
      <span class="hljs-keyword">if</span> (options.<span class="hljs-property">name</span>) {
        options.<span class="hljs-property">components</span>[options.<span class="hljs-property">name</span>] = <span class="hljs-title class_">Ctor</span>
      }
    }
  }
  <span class="hljs-keyword">return</span> options
}

<span class="copy-code-btn">复制代码</span></code></pre>
                            <h2 data-id="heading-6">resolveModifiedOptions</h2>
                            <blockquote>
                              <p>/src/core/instance/init.js</p>
                            </blockquote>
                            <pre><code class="hljs language-javascript copyable" lang="javascript"><span class="hljs-comment">/**
 * 解析构造函数选项中后续被修改或者增加的选项
 */</span>
<span class="hljs-keyword">function</span> <span class="hljs-title function_">resolveModifiedOptions</span> (<span class="hljs-title class_">Ctor</span>: <span class="hljs-title class_">Class</span>&#x3C;<span class="hljs-title class_">Component</span>>): ?<span class="hljs-title class_">Object</span> {
  <span class="hljs-keyword">let</span> modified
  <span class="hljs-comment">// 构造函数选项</span>
  <span class="hljs-keyword">const</span> latest = <span class="hljs-title class_">Ctor</span>.<span class="hljs-property">options</span>
  <span class="hljs-comment">// 密封的构造函数选项，备份</span>
  <span class="hljs-keyword">const</span> sealed = <span class="hljs-title class_">Ctor</span>.<span class="hljs-property">sealedOptions</span>
  <span class="hljs-comment">// 对比两个选项，记录不一致的选项</span>
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> key <span class="hljs-keyword">in</span> latest) {
    <span class="hljs-keyword">if</span> (latest[key] !== sealed[key]) {
      <span class="hljs-keyword">if</span> (!modified) modified = {}
      modified[key] = latest[key]
    }
  }
  <span class="hljs-keyword">return</span> modified
}

<span class="copy-code-btn">复制代码</span></code></pre>
                            <h2 data-id="heading-7">mergeOptions</h2>
                            <blockquote>
                              <p>/src/core/util/options.js</p>
                            </blockquote>
                            <pre><code class="hljs language-javascript copyable" lang="javascript"><span class="hljs-comment">/**
 * 合并两个选项，出现相同配置项时，子选项会覆盖父选项的配置
 */</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">mergeOptions</span> (
  <span class="hljs-attr">parent</span>: <span class="hljs-title class_">Object</span>,
  <span class="hljs-attr">child</span>: <span class="hljs-title class_">Object</span>,
  vm?: <span class="hljs-title class_">Component</span>
): <span class="hljs-title class_">Object</span> {
  <span class="hljs-keyword">if</span> (process.<span class="hljs-property">env</span>.<span class="hljs-property">NODE_ENV</span> !== <span class="hljs-string">'production'</span>) {
    <span class="hljs-title function_">checkComponents</span>(child)
  }

  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> child === <span class="hljs-string">'function'</span>) {
    child = child.<span class="hljs-property">options</span>
  }

  <span class="hljs-comment">// 标准化 props、inject、directive 选项，方便后续程序的处理</span>
  <span class="hljs-title function_">normalizeProps</span>(child, vm)
  <span class="hljs-title function_">normalizeInject</span>(child, vm)
  <span class="hljs-title function_">normalizeDirectives</span>(child)

  <span class="hljs-comment">// 处理原始 child 对象上的 extends 和 mixins，分别执行 mergeOptions，将这些继承而来的选项合并到 parent</span>
  <span class="hljs-comment">// mergeOptions 处理过的对象会含有 _base 属性</span>
  <span class="hljs-keyword">if</span> (!child.<span class="hljs-property">_base</span>) {
    <span class="hljs-keyword">if</span> (child.<span class="hljs-property">extends</span>) {
      parent = <span class="hljs-title function_">mergeOptions</span>(parent, child.<span class="hljs-property">extends</span>, vm)
    }
    <span class="hljs-keyword">if</span> (child.<span class="hljs-property">mixins</span>) {
      <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>, l = child.<span class="hljs-property">mixins</span>.<span class="hljs-property">length</span>; i &#x3C; l; i++) {
        parent = <span class="hljs-title function_">mergeOptions</span>(parent, child.<span class="hljs-property">mixins</span>[i], vm)
      }
    }
  }

  <span class="hljs-keyword">const</span> options = {}
  <span class="hljs-keyword">let</span> key
  <span class="hljs-comment">// 遍历 父选项</span>
  <span class="hljs-keyword">for</span> (key <span class="hljs-keyword">in</span> parent) {
    <span class="hljs-title function_">mergeField</span>(key)
  }

  <span class="hljs-comment">// 遍历 子选项，如果父选项不存在该配置，则合并，否则跳过，因为父子拥有同一个属性的情况在上面处理父选项时已经处理过了，用的子选项的值</span>
  <span class="hljs-keyword">for</span> (key <span class="hljs-keyword">in</span> child) {
    <span class="hljs-keyword">if</span> (!<span class="hljs-title function_">hasOwn</span>(parent, key)) {
      <span class="hljs-title function_">mergeField</span>(key)
    }
  }

  <span class="hljs-comment">// 合并选项，childVal 优先级高于 parentVal</span>
  <span class="hljs-keyword">function</span> <span class="hljs-title function_">mergeField</span> (key) {
    <span class="hljs-comment">// strats = Object.create(null)</span>
    <span class="hljs-keyword">const</span> strat = strats[key] || defaultStrat
    <span class="hljs-comment">// 值为如果 childVal 存在则优先使用 childVal，否则使用 parentVal</span>
    options[key] = <span class="hljs-title function_">strat</span>(parent[key], child[key], vm, key)
  }
  <span class="hljs-keyword">return</span> options
}

<span class="copy-code-btn">复制代码</span></code></pre>
                            <h2 data-id="heading-8">initInjections</h2>
                            <blockquote>
                              <p>/src/core/instance/inject.js</p>
                            </blockquote>
                            <pre><code class="hljs language-javascript copyable" lang="javascript"><span class="hljs-comment">/**
 * 初始化 inject 配置项
 *   1、得到 result[key] = val
 *   2、对结果数据进行响应式处理，代理每个 key 到 vm 实例
 */</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">initInjections</span> (<span class="hljs-attr">vm</span>: <span class="hljs-title class_">Component</span>) {
  <span class="hljs-comment">// 解析 inject 配置项，然后从祖代组件的配置中找到 配置项中每一个 key 对应的 val，最后得到 result[key] = val 的结果</span>
  <span class="hljs-keyword">const</span> result = <span class="hljs-title function_">resolveInject</span>(vm.<span class="hljs-property">$options</span>.<span class="hljs-property">inject</span>, vm)
  <span class="hljs-comment">// 对 result 做 数据响应式处理，也有代理 inject 配置中每个 key 到 vm 实例的作用。</span>
  <span class="hljs-comment">// 不不建议在子组件去更改这些数据，因为一旦祖代组件中 注入的 provide 发生更改，你在组件中做的更改就会被覆盖</span>
  <span class="hljs-keyword">if</span> (result) {
    <span class="hljs-title function_">toggleObserving</span>(<span class="hljs-literal">false</span>)
    <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">keys</span>(result).<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">key</span> =></span> {
      <span class="hljs-comment">/* istanbul ignore else */</span>
      <span class="hljs-keyword">if</span> (process.<span class="hljs-property">env</span>.<span class="hljs-property">NODE_ENV</span> !== <span class="hljs-string">'production'</span>) {
        <span class="hljs-title function_">defineReactive</span>(vm, key, result[key], <span class="hljs-function">() =></span> {
          <span class="hljs-title function_">warn</span>(
            <span class="hljs-string">`Avoid mutating an injected value directly since the changes will be `</span> +
            <span class="hljs-string">`overwritten whenever the provided component re-renders. `</span> +
            <span class="hljs-string">`injection being mutated: "<span class="hljs-subst">${key}</span>"`</span>,
            vm
          )
        })
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-title function_">defineReactive</span>(vm, key, result[key])
      }
    })
    <span class="hljs-title function_">toggleObserving</span>(<span class="hljs-literal">true</span>)
  }
}

<span class="copy-code-btn">复制代码</span></code></pre>
                            <h2 data-id="heading-9">resolveInject</h2>
                            <blockquote>
                              <p>/src/core/instance/inject.js</p>
                            </blockquote>
                            <pre><code class="hljs language-javascript copyable" lang="javascript"><span class="hljs-comment">/**
 * 解析 inject 配置项，从祖代组件的 provide 配置中找到 key 对应的值，否则用 默认值，最后得到 result[key] = val
 * inject 对象肯定是以下这个结构，因为在 合并 选项时对组件配置对象做了标准化处理
 * <span class="hljs-doctag">@param</span> {<span class="hljs-type">*</span>} inject = {
 *  key: {
 *    from: provideKey,
 *    default: xx
 *  }
 * }
 */</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">resolveInject</span> (<span class="hljs-attr">inject</span>: any, <span class="hljs-attr">vm</span>: <span class="hljs-title class_">Component</span>): ?<span class="hljs-title class_">Object</span> {
  <span class="hljs-keyword">if</span> (inject) {
    <span class="hljs-comment">// inject is :any because flow is not smart enough to figure out cached</span>
    <span class="hljs-keyword">const</span> result = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">create</span>(<span class="hljs-literal">null</span>)
    <span class="hljs-comment">// inject 配置项的所有的 key</span>
    <span class="hljs-keyword">const</span> keys = hasSymbol
      ? <span class="hljs-title class_">Reflect</span>.<span class="hljs-title function_">ownKeys</span>(inject)
      : <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">keys</span>(inject)

    <span class="hljs-comment">// 遍历 key</span>
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &#x3C; keys.<span class="hljs-property">length</span>; i++) {
      <span class="hljs-keyword">const</span> key = keys[i]
      <span class="hljs-comment">// 跳过 __ob__ 对象</span>
      <span class="hljs-comment">// #6574 in case the inject object is observed...</span>
      <span class="hljs-keyword">if</span> (key === <span class="hljs-string">'__ob__'</span>) <span class="hljs-keyword">continue</span>
      <span class="hljs-comment">// 拿到 provide 中对应的 key</span>
      <span class="hljs-keyword">const</span> provideKey = inject[key].<span class="hljs-property">from</span>
      <span class="hljs-keyword">let</span> source = vm
      <span class="hljs-comment">// 遍历所有的祖代组件，直到 根组件，找到 provide 中对应 key 的值，最后得到 result[key] = provide[provideKey]</span>
      <span class="hljs-keyword">while</span> (source) {
        <span class="hljs-keyword">if</span> (source.<span class="hljs-property">_provided</span> &#x26;&#x26; <span class="hljs-title function_">hasOwn</span>(source.<span class="hljs-property">_provided</span>, provideKey)) {
          result[key] = source.<span class="hljs-property">_provided</span>[provideKey]
          <span class="hljs-keyword">break</span>
        }
        source = source.<span class="hljs-property">$parent</span>
      }
      <span class="hljs-comment">// 如果上一个循环未找到，则采用 inject[key].default，如果没有设置 default 值，则抛出错误</span>
      <span class="hljs-keyword">if</span> (!source) {
        <span class="hljs-keyword">if</span> (<span class="hljs-string">'default'</span> <span class="hljs-keyword">in</span> inject[key]) {
          <span class="hljs-keyword">const</span> provideDefault = inject[key].<span class="hljs-property">default</span>
          result[key] = <span class="hljs-keyword">typeof</span> provideDefault === <span class="hljs-string">'function'</span>
            ? provideDefault.<span class="hljs-title function_">call</span>(vm)
            : provideDefault
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (process.<span class="hljs-property">env</span>.<span class="hljs-property">NODE_ENV</span> !== <span class="hljs-string">'production'</span>) {
          <span class="hljs-title function_">warn</span>(<span class="hljs-string">`Injection "<span class="hljs-subst">${key}</span>" not found`</span>, vm)
        }
      }
    }
    <span class="hljs-keyword">return</span> result
  }
}

<span class="copy-code-btn">复制代码</span></code></pre>
                            <h2 data-id="heading-10">initProvide</h2>
                            <blockquote>
                              <p>/src/core/instance/inject.js</p>
                            </blockquote>
                            <pre><code class="hljs language-javascript copyable" lang="javascript"><span class="hljs-comment">/**
 * 解析组件配置项上的 provide 对象，将其挂载到 vm._provided 属性上 
 */</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">initProvide</span> (<span class="hljs-attr">vm</span>: <span class="hljs-title class_">Component</span>) {
  <span class="hljs-keyword">const</span> provide = vm.<span class="hljs-property">$options</span>.<span class="hljs-property">provide</span>
  <span class="hljs-keyword">if</span> (provide) {
    vm.<span class="hljs-property">_provided</span> = <span class="hljs-keyword">typeof</span> provide === <span class="hljs-string">'function'</span>
      ? provide.<span class="hljs-title function_">call</span>(vm)
      : provide
  }
}

<span class="copy-code-btn">复制代码</span></code></pre>
                            <h1 data-id="heading-11">总结</h1>
                            <p>
                              Vue 的初始化过程（new Vue(options)）都做了什么？
                            </p>
                            <ul>
                              <li>
                                <p>处理组件配置项</p>
                                <ul>
                                  <li>
                                    <p>
                                      初始化根组件时进行了选项合并操作，将全局配置合并到根组件的局部配置上
                                    </p>
                                  </li>
                                  <li>
                                    <p>
                                      初始化每个子组件时做了一些性能优化，将组件配置对象上的一些深层次属性放到
                                      vm.$options 选项中，以提高代码的执行效率
                                    </p>
                                  </li>
                                </ul>
                              </li>
                              <li>
                                <p>
                                  初始化组件实例的关系属性，比如
                                  $parent、$children、$root、$refs 等
                                </p>
                              </li>
                              <li>
                                <p>处理自定义事件</p>
                              </li>
                              <li>
                                <p>调用 beforeCreate 钩子函数</p>
                              </li>
                              <li>
                                <p>
                                  初始化组件的 inject 配置项，得到
                                  <code>ret[key] = val</code>
                                  形式的配置对象，然后对该配置对象进行浅层的响应式处理（只处理了对象第一层数据），并代理每个
                                  key 到 vm 实例上
                                </p>
                              </li>
                              <li>
                                <p>
                                  数据响应式，处理
                                  props、methods、data、computed、watch 等选项
                                </p>
                              </li>
                              <li>
                                <p>
                                  解析组件配置项上的 provide 对象，将其挂载到
                                  vm._provided 属性上
                                </p>
                              </li>
                              <li>
                                <p>调用 created 钩子函数</p>
                              </li>
                              <li>
                                <p>
                                  如果发现配置项上有 el 选项，则自动调用 $mount
                                  方法，也就是说有了 el 选项，就不需要再手动调用
                                  $mount 方法，反之，没提供 el 选项则必须调用
                                  $mount
                                </p>
                              </li>
                              <li>
                                <p>接下来则进入挂载阶段</p>
                              </li>
                            </ul>
                            <h1 data-id="heading-12">链接</h1>
                            <ul>
                              <li>
                                <p>
                                  <a
                                    href="https://link.juejin.cn?target=https%3A%2F%2Fgitee.com%2Fliyongning%2Ftypora-image-bed%2Fraw%2Fmaster%2F202202171742614.jpg"
                                    target="_blank"
                                    title="https://gitee.com/liyongning/typora-image-bed/raw/master/202202171742614.jpg"
                                    ref="nofollow noopener noreferrer"
                                    >配套视频，关注微信公众号回复</a
                                  >："精通 Vue 技术栈源码原理视频版" 获取
                                </p>
                              </li>
                              <li>
                                <p>
                                  <a
                                    href="https://link.juejin.cn?target=https%3A%2F%2Fmp.weixin.qq.com%2Fmp%2Fappmsgalbum%3F__biz%3DMzA3NTk4NjQ1OQ%3D%3D%26action%3Dgetalbum%26album_id%3D2273541436891693065%23wechat_redirect"
                                    target="_blank"
                                    title="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzA3NTk4NjQ1OQ==&#x26;action=getalbum&#x26;album_id=2273541436891693065#wechat_redirect"
                                    ref="nofollow noopener noreferrer"
                                    >精通 Vue 技术栈源码原理 专栏</a
                                  >
                                </p>
                              </li>
                              <li>
                                <p>
                                  <a
                                    href="https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fliyongning%2FVue"
                                    target="_blank"
                                    title="https://github.com/liyongning/Vue"
                                    ref="nofollow noopener noreferrer"
                                    >github 仓库 liyongning/Vue</a
                                  >
                                  欢迎 Star
                                </p>
                              </li>
                            </ul>
                            <p>
                              感谢各位的：<strong>点赞</strong>、<strong>收藏</strong>和<strong>评论</strong>，我们下期见。
                            </p>
                            <hr />
                            <p>
                              <strong
                                >当学习成为了习惯，知识也就变成了常识。</strong
                              >
                              感谢各位的
                              <strong>点赞</strong
                              >、<strong>收藏</strong>和<strong>评论</strong>。
                            </p>
                            <p>
                              新视频和文章会第一时间在微信公众号发送，欢迎关注：<a
                                href="https://link.juejin.cn?target=https%3A%2F%2Fgitee.com%2Fliyongning%2Ftypora-image-bed%2Fraw%2Fmaster%2F202202171742614.jpg"
                                target="_blank"
                                title="https://gitee.com/liyongning/typora-image-bed/raw/master/202202171742614.jpg"
                                ref="nofollow noopener noreferrer"
                                >李永宁lyn</a
                              >
                            </p>
                            <p>
                              文章已收录到
                              <a
                                href="https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fliyongning%2Fblog"
                                target="_blank"
                                title="https://github.com/liyongning/blog"
                                ref="nofollow noopener noreferrer"
                                >github 仓库 liyongning/blog</a
                              >，欢迎 Watch 和 Star。
                            </p>
                          </body>
                        </html>
                      </div>
                    </div>
                  </article>
                  <!---->
                  <div class="article-end" data-v-1e8be6f4 data-v-7a561fad>
                    <div class="tag-list-box" data-v-1e8be6f4 data-v-7a561fad>
                      <div class="tag-list" data-v-1e8be6f4 data-v-7a561fad>
                        <div
                          class="tag-list-title"
                          data-v-1e8be6f4
                          data-v-7a561fad
                        >
                          分类：
                        </div>
                        <a
                          href="/frontend"
                          target="_blank"
                          rel=""
                          class="item category-item"
                          data-v-7a561fad
                          ><span class="tag-title" data-v-7a561fad
                            >前端</span
                          ></a
                        >
                      </div>
                      <div class="tag-list" data-v-1e8be6f4 data-v-7a561fad>
                        <div
                          class="tag-list-title"
                          data-v-1e8be6f4
                          data-v-7a561fad
                        >
                          标签：
                        </div>
                        <div
                          class="tag-list-container"
                          data-v-1e8be6f4
                          data-v-7a561fad
                        >
                          <a
                            href="/tag/JavaScript"
                            target="_blank"
                            rel=""
                            class="item tag-item"
                            data-v-7a561fad
                            ><span class="tag-title" data-v-7a561fad
                              >JavaScript</span
                            ></a
                          ><a
                            href="/tag/Vue.js"
                            target="_blank"
                            rel=""
                            class="item tag-item"
                            data-v-7a561fad
                            ><span class="tag-title" data-v-7a561fad
                              >Vue.js</span
                            ></a
                          ><a
                            href="/tag/%E5%89%8D%E7%AB%AF"
                            target="_blank"
                            rel=""
                            class="item tag-item"
                            data-v-7a561fad
                            ><span class="tag-title" data-v-7a561fad
                              >前端</span
                            ></a
                          >
                        </div>
                      </div>
                      <!---->
                    </div>
                    <!---->
                    <div
                      class="extension-banner"
                      data-v-fea06212
                      data-v-7a561fad
                    >
                      <span class="banner-icon" data-v-fea06212></span>
                      <div class="banner-wrapper" data-v-fea06212>
                        <a class="banner-title" data-v-fea06212>
                          安装掘金浏览器插件
                        </a>
                        <div class="banner-content" data-v-fea06212>
                          多内容聚合浏览、多引擎快捷搜索、多工具便捷提效、多模式随心畅享，你想要的，这里都有！
                        </div>
                      </div>
                      <a class="banner-action" data-v-fea06212>前往安装</a>
                    </div>
                  </div>
                  <!---->
                  <!---->
                  <!---->
                  <!---->
                  <!---->
                  <!---->
                </div>
                <!---->
                <!---->
                <div
                  st:block="sidebar"
                  class="sidebar"
                  data-v-cceb3a2e
                  data-v-7a561fad
                >
                  <div
                    class="sidebar-block author-block pure"
                    data-v-71f2d09e
                    data-v-8e1847b4
                    data-v-cceb3a2e
                  >
                    <a
                      href="/user/1028798616461326"
                      target="_blank"
                      rel=""
                      class="user-item item"
                      data-v-8e1847b4
                      ><img
                        loading="eager"
                        src="https://p3-passport.byteimg.com/img/user-avatar/ecfb3bbd73753344105b06067757a70a~100x100.image"
                        alt=""
                        class="lazy avatar avatar"
                        data-v-248050e4
                        data-v-0b45085c
                        data-v-8e1847b4
                      />
                      <div class="info-box" data-v-8e1847b4>
                        <span
                          to="[object Object]"
                          blank="true"
                          class="username"
                          data-v-2b2ca9ee
                          data-v-8e1847b4
                          ><span
                            class="name"
                            style="max-width: 128px"
                            data-v-2b2ca9ee
                          >
                            李永宁
                          </span>
                          <span
                            blank="true"
                            class="rank"
                            data-v-3c1a13dc
                            data-v-2b2ca9ee
                            ><img
                              src=""
                              alt="lv-5"
                              title="创作等级"
                              class="lazy"
                              style="aspect-ratio: NaN"
                              data-v-248050e4
                              data-v-3c1a13dc
                          /></span>
                          <!---->
                          <!---->
                        </span>
                        <div
                          title="微信搜：李永宁lyn @ B 站搜：李永宁_lyn"
                          class="position"
                          data-v-8e1847b4
                        >
                          微信搜：李永宁lyn @ B 站搜：李永宁_lyn
                        </div>
                      </div>
                    </a>
                    <div class="operate-btn" data-v-71f2d09e data-v-8e1847b4>
                      <button
                        st:name="followBtn"
                        class="ui-btn follow-btn primary large default attention"
                        data-v-2afc21b6
                        data-v-8e1847b4
                      >
                        <!---->
                        关注
                      </button>
                      <a
                        href="/notification/im?participantId=1028798616461326"
                        class="im-button im-btn"
                        data-v-11443840
                        data-v-8e1847b4
                      >
                        <!---->
                        <div data-v-11443840>私信</div>
                      </a>
                    </div>
                    <div class="cut-off" data-v-71f2d09e data-v-8e1847b4></div>
                    <div class="stat-item item" data-v-71f2d09e data-v-8e1847b4>
                      <svg
                        xmlns="http://www.w3.org/2000/svg"
                        width="25"
                        height="26"
                        viewBox="0 0 25 26"
                        class="zan"
                        data-v-71f2d09e
                        data-v-8e1847b4
                      >
                        <g
                          fill="none"
                          fill-rule="evenodd"
                          transform="translate(0 .57)"
                          data-v-71f2d09e
                          data-v-8e1847b4
                        >
                          <ellipse
                            cx="12.5"
                            cy="12.57"
                            fill="#E1EFFF"
                            rx="12.5"
                            ry="12.57"
                            data-v-71f2d09e
                            data-v-8e1847b4
                          ></ellipse>
                          <path
                            fill="#7BB9FF"
                            d="M8.596 11.238V19H7.033C6.463 19 6 18.465 6 17.807v-5.282c0-.685.483-1.287 1.033-1.287h1.563zm4.275-4.156A1.284 1.284 0 0 1 14.156 6c.885.016 1.412.722 1.595 1.07.334.638.343 1.687.114 2.361-.207.61-.687 1.412-.687 1.412h3.596c.38 0 .733.178.969.488.239.317.318.728.21 1.102l-1.628 5.645a1.245 1.245 0 0 1-1.192.922h-7.068v-7.889c1.624-.336 2.623-2.866 2.806-4.029z"
                            data-v-71f2d09e
                            data-v-8e1847b4
                          ></path>
                        </g>
                      </svg>
                      <span class="content" data-v-71f2d09e data-v-8e1847b4>
                        获得点赞
                        <span
                          class="count"
                          style="display: none"
                          data-v-71f2d09e
                          data-v-8e1847b4
                        >
                           6,253
                        </span></span
                      >
                    </div>
                    <div class="stat-item item" data-v-71f2d09e data-v-8e1847b4>
                      <svg
                        width="25"
                        height="25"
                        viewBox="0 0 25 25"
                        class="icon stat-view-icon"
                        data-v-71f2d09e
                        data-v-8e1847b4
                      >
                        <g
                          fill="none"
                          fill-rule="evenodd"
                          data-v-71f2d09e
                          data-v-8e1847b4
                        >
                          <circle
                            cx="12.5"
                            cy="12.5"
                            r="12.5"
                            fill="#E1EFFF"
                            data-v-71f2d09e
                            data-v-8e1847b4
                          ></circle>
                          <path
                            fill="#7BB9FF"
                            d="M4 12.5S6.917 7 12.75 7s8.75 5.5 8.75 5.5-2.917 5.5-8.75 5.5S4 12.5 4 12.5zm8.75 2.292c1.208 0 2.188-1.026 2.188-2.292 0-1.266-.98-2.292-2.188-2.292-1.208 0-2.188 1.026-2.188 2.292 0 1.266.98 2.292 2.188 2.292z"
                            data-v-71f2d09e
                            data-v-8e1847b4
                          ></path>
                        </g>
                      </svg>
                      <span class="content" data-v-71f2d09e data-v-8e1847b4>
                        文章被阅读
                        <span
                          class="count"
                          style="display: none"
                          data-v-71f2d09e
                          data-v-8e1847b4
                        >
                           600,619
                        </span></span
                      >
                    </div>
                    <!---->
                  </div>
                  <!---->
                  <!---->
                  <!---->
                  <!---->
                  <div
                    class="sticky-block-box"
                    style="display: none"
                    data-v-cceb3a2e
                  >
                    <div
                      class="sidebar-block catalog-block pure"
                      style="display: none"
                      data-v-71f2d09e
                      data-v-79f817f2
                      data-v-cceb3a2e
                    >
                      <nav
                        class="article-catalog"
                        style="display: none"
                        data-v-6c50ea67
                        data-v-79f817f2
                      >
                        <div class="catalog-title" data-v-6c50ea67>目录</div>
                        <div class="catalog-body" data-v-6c50ea67>
                          <ul
                            class="catalog-list"
                            style="margin-top: 0px"
                            data-v-6c50ea67
                          ></ul>
                        </div>
                      </nav>
                    </div>
                    <!---->
                  </div>
                </div>
                <!---->
              </div>
              <!---->
            </main>
            <!---->
          </div>
          <!---->
          <div class="global-component-box">
            <!---->
            <!---->
            <!---->
            <!---->
            <!---->
            <!---->
          </div>
          <!---->
          <!---->
          <!---->
          <!---->
          <!---->
          <!---->
          <!---->
          <!---->
          <!---->
          <div
            data-transfer="true"
            align-center=""
            class="risk-modal byte-modal"
          >
            <div
              class="byte-modal__mask"
              style="z-index: 8858; display: none"
            ></div>
            <div
              class="byte-modal__wrapper"
              style="z-index: 8858; display: none"
            >
              <div class="byte-modal__content" style="width: 350px">
                <!---->
                <div class="byte-modal__body">
                  <div class="risk-modal-inner">
                    <div class="risk-modal-title">温馨提示</div>
                    <div>当前操作失败，如有疑问，可点击申诉</div>
                    <div class="risk-modal-footer">
                      <button
                        type="button"
                        class="cancel-button risk-button byte-btn byte-btn--default byte-btn--large"
                      >
                        <!---->
                        <!----><span><span>前往申诉</span></span>
                      </button>
                      <button
                        type="button"
                        class="risk-button byte-btn byte-btn--primary byte-btn--large"
                      >
                        <!---->
                        <!----><span><span>我知道了</span></span>
                      </button>
                    </div>
                  </div>
                </div>
                <!---->
              </div>
            </div>
          </div>
          <!---->
          <!---->
          <!---->
          <!---->
          <!---->
        </div>
      </div>
    </div>
    <script>
      window.__NUXT__ = (function (
        a,
        b,
        c,
        d,
        e,
        f,
        g,
        h,
        i,
        j,
        k,
        l,
        m,
        n,
        o,
        p,
        q,
        r,
        s,
        t,
        u,
        v,
        w,
        x,
        y,
        z,
        A,
        B,
        C,
        D,
        E,
        F,
        G,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R
      ) {
        u.loading = a;
        u.skeleton = d;
        u.cursor = f;
        u.data = [];
        u.total = b;
        u.hasMore = d;
        J.id = A;
        J.self_description = p;
        J.followed = a;
        J.viewerIsFollowing = p;
        J.community = p;
        J.subscribedTagCount = b;
        J.wroteBookCount = b;
        J.boughtBookCount = b;
        J.isBindedPhone = a;
        J.level = t;
        J.user_id = A;
        J.user_name = H;
        J.company = "B 站搜：李永宁_lyn";
        J.job_title = "微信搜：李永宁lyn";
        J.avatar_large =
          "https:\u002F\u002Fp9-passport.byteacctimg.com\u002Fimg\u002Fuser-avatar\u002Fecfb3bbd73753344105b06067757a70a~300x300.image";
        J.description = "http:\u002F\u002Fgithub.com\u002Fliyongning";
        J.followee_count = 21;
        J.follower_count = 5247;
        J.post_article_count = 70;
        J.digg_article_count = 76;
        J.got_digg_count = 6253;
        J.got_view_count = 600619;
        J.post_shortmsg_count = 30;
        J.digg_shortmsg_count = 19;
        J.isfollowed = a;
        J.favorable_author = g;
        J.power = I;
        J.study_point = b;
        J.university = { university_id: f, name: e, logo: e };
        J.major = { major_id: f, parent_id: f, name: e };
        J.student_status = b;
        J.select_event_count = b;
        J.select_online_course_count = b;
        J.identity = b;
        J.is_select_annual = d;
        J.select_annual_rank = b;
        J.annual_list_type = b;
        J.extraMap = {};
        J.is_logout = b;
        J.annual_info = [];
        J.account_amount = b;
        J.user_growth_info = {
          user_id: 1028798616461326,
          jpower: I,
          jscore: 513.7,
          jpower_level: t,
          jscore_level: t,
          jscore_title: "先锋掘友",
          author_achievement_list: [g],
          vip_level: b,
          vip_title: e,
          jscore_next_level_score: 2000,
          jscore_this_level_mini_score: 500,
        };
        J.is_vip = a;
        J.become_author_days = b;
        J.collection_set_article_count = b;
        J.recommend_article_count_daily = b;
        J.article_collect_count_daily = b;
        J.juejinPower = I;
        J.jobTitle = "微信搜：李永宁lyn";
        J.roles = {
          isBookAuthor: a,
          isFavorableAuthor: d,
          isCobuilder: a,
          isAdmin: a,
        };
        J.username = H;
        J.blogAddress = p;
        J.selfDescription = "http:\u002F\u002Fgithub.com\u002Fliyongning";
        J.beLikedCount = 6253;
        J.beReadCount = 600619;
        J.followerCount = 5247;
        J.followingCount = 21;
        J.collectionCount = b;
        J.createdCollectionCount = b;
        J.followingCollectionCount = b;
        J.postedPostsCount = 70;
        J.pinCount = 30;
        J.likedArticleCount = 76;
        J.likedPinCount = 19;
        J.avatar =
          "https:\u002F\u002Fp9-passport.byteacctimg.com\u002Fimg\u002Fuser-avatar\u002Fecfb3bbd73753344105b06067757a70a~300x300.image";
        J.latestLoginedInAt = c;
        J.createdAt = c;
        J.updatedAt = c;
        J.phoneNumber = e;
        J.titleDescription = e;
        J.followeesCount = 21;
        J.applyEventCount = b;
        J.need_lead = b;
        J.followTopicCnt = b;
        return {
          layout: "default",
          data: [{ renderPost: d, additionalDataUseCSR: d }],
          fetch: [
            {
              bdPageUrlForNav:
                "https:\u002F\u002Fbd.juejin.cn?utm_campaign=bd&utm_source=web&utm_medium=nav",
              queryString: e,
              isShowUserDropdownList: a,
              isShowAddMoreList: a,
              isFocus: a,
              isPhoneMenuShow: a,
              visibleBadge: a,
              placeholder: e,
              hiddenProperty: "hidden",
              searchHistoryVisible: a,
              searchHistoryItems: [],
              tabBadge: c,
              isChangePlaceholder: d,
              showMallBridge: a,
              removeSearchInputKeyupListener: c,
            },
          ],
          error: c,
          state: {
            view: {
              activityIndex: {
                activityList: [],
                pageInfo: { hasNextPage: a, endCursor: e },
                afterPosition: e,
                activityListIsLoading: d,
                activityListIsError: a,
                userActivityList: [],
                placeholder: e,
                actionType: {
                  FETCH: "@\u002Fview\u002Factivity-index\u002FFETCH",
                  FETCH_RECOMMEND_LIST:
                    "@\u002Fview\u002Factivity-index\u002FFETCH_RECOMMEND_LIST",
                  RESET_ACTIVITY_LIST:
                    "@\u002Fview\u002Factivity-index\u002FRESET_ACTIVITY_LIST",
                  FETCH_USER_ACTIVITY_LIST:
                    "@\u002Fview\u002Factivity-index\u002FFETCH_USER_ACTIVITY_LIST",
                  FETCH_NEW_COUNT:
                    "@\u002Fview\u002Factivity-index\u002FFETCH_NEW_COUNT",
                  DELETE_ACTIVITY:
                    "@\u002Fview\u002Factivity-index\u002FDELETE_ACTIVITY",
                  TOGGLE_FOLLOW_USER:
                    "@\u002Fview\u002Factivity-index\u002FTOGGLE_FOLLOW_USER",
                  FETCH_ENTRY_COMMENT_LIST:
                    "@\u002Fview\u002Factivity-index\u002FFETCH_ENTRY_COMMENT_LIST",
                  UPDATE_LIST_LOADING:
                    "@\u002Fview\u002Factivity-index\u002FUPDATE_LIST_LOADING",
                  RESET: "@\u002Fview\u002Factivity-index\u002FRESET",
                },
                hotList: {
                  list: [],
                  after: e,
                  loading: a,
                  hasNextPage: a,
                  actionType: {
                    UPDATE_STATE:
                      "@\u002Fview\u002Factivity-index\u002Fhot-list\u002FUPDATE_STATE",
                    FETCH_MORE:
                      "@\u002Fview\u002Factivity-index\u002Fhot-list\u002FFETCH_MORE",
                    FETCH:
                      "@\u002Fview\u002Factivity-index\u002Fhot-list\u002FFETCH",
                    RESET:
                      "@\u002Fview\u002Factivity-index\u002Fhot-list\u002FRESET",
                  },
                },
                sidebar: {
                  bannerList: [],
                  actionType: {
                    RESET:
                      "@\u002Fview\u002Factivity-index\u002Fsidebar\u002FRESET",
                    UPDATE_STATE:
                      "@\u002Fview\u002Factivity-index\u002Fsidebar\u002FUPDATE_STATE",
                    FETCH_BANNER:
                      "@\u002Fview\u002Factivity-index\u002Fsidebar\u002FFETCH_BANNER",
                  },
                  recommend: {
                    pageSize: h,
                    page: b,
                    total: b,
                    pointer: c,
                    lastPointer: c,
                    list: [],
                    loading: a,
                    error: c,
                    canPrev: d,
                    canNext: d,
                    linkList: [],
                    lastFetchOnServer: a,
                    actionType: {
                      UPDATE:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Frecommend-topic-list\u002FUPDATE",
                      FETCH:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Frecommend-topic-list\u002FFETCH",
                      FORCE_FETCH:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Frecommend-topic-list\u002FFORCE_FETCH",
                      FETCH_MORE:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Frecommend-topic-list\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Frecommend-topic-list\u002FRESET",
                    },
                    after: b,
                  },
                  followed: {
                    pageSize: h,
                    page: b,
                    total: b,
                    pointer: c,
                    lastPointer: c,
                    list: [],
                    loading: a,
                    error: c,
                    canPrev: d,
                    canNext: d,
                    linkList: [],
                    lastFetchOnServer: a,
                    actionType: {
                      UPDATE:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Ffollowed-topic-list\u002FUPDATE",
                      FETCH:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Ffollowed-topic-list\u002FFETCH",
                      FORCE_FETCH:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Ffollowed-topic-list\u002FFORCE_FETCH",
                      FETCH_MORE:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Ffollowed-topic-list\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Ffollowed-topic-list\u002FRESET",
                    },
                    after: b,
                  },
                  recommendPin: {
                    list: [],
                    after: e,
                    loading: a,
                    hasNextPage: d,
                    actionType: {
                      UPDATE_STATE:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Frecommend-pin-list\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Frecommend-pin-list\u002FFETCH_MORE",
                      FETCH:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Frecommend-pin-list\u002FFETCH",
                      RESET:
                        "@\u002Fview\u002Factivity-index\u002Fsidebar\u002Frecommend-pin-list\u002FRESET",
                    },
                  },
                },
                topicPinList: {
                  pageSize: h,
                  page: g,
                  total: b,
                  pointer: c,
                  lastPointer: c,
                  list: [],
                  loading: a,
                  error: c,
                  canPrev: d,
                  canNext: d,
                  linkList: [],
                  lastFetchOnServer: a,
                  actionType: {
                    UPDATE:
                      "@\u002Fview\u002Factivity-index\u002Ftopic-pin-list\u002FUPDATE",
                    FETCH:
                      "@\u002Fview\u002Factivity-index\u002Ftopic-pin-list\u002FFETCH",
                    FORCE_FETCH:
                      "@\u002Fview\u002Factivity-index\u002Ftopic-pin-list\u002FFORCE_FETCH",
                    FETCH_MORE:
                      "@\u002Fview\u002Factivity-index\u002Ftopic-pin-list\u002FFETCH_MORE",
                    RESET:
                      "@\u002Fview\u002Factivity-index\u002Ftopic-pin-list\u002FRESET",
                  },
                  topicId: e,
                  navList: [
                    { type: l, name: l, title: "推荐 ", id: l },
                    { type: n, name: n, title: "热门 ", id: n },
                    { type: q, name: q, title: "关注 ", id: q },
                    {
                      type: j,
                      name: "opensource",
                      title: "开源推荐 ",
                      id: "5c09ea2b092dcb42c740fe73",
                    },
                    {
                      type: j,
                      name: "recruitment",
                      title: "内推招聘",
                      id: "5abb61e1092dcb4620ca3322",
                    },
                    {
                      type: j,
                      name: "dating",
                      title: "掘金相亲",
                      id: "5abcaa67092dcb4620ca335c",
                    },
                    {
                      type: j,
                      name: "slacking",
                      title: "上班摸鱼",
                      id: "5c106be9092dcb2cc5de7257",
                    },
                    {
                      type: j,
                      name: "app",
                      title: "应用安利",
                      id: "5b514af1092dcb61bd72800d",
                    },
                    {
                      type: j,
                      name: "tool",
                      title: "开发工具",
                      id: "5abb67d2092dcb4620ca3324",
                    },
                    {
                      type: j,
                      name: "news",
                      title: "New资讯",
                      id: "5c46a17f092dcb4737217152",
                    },
                  ],
                  sortType: r,
                },
              },
              search: {
                search_result_from: b,
                query: e,
                list: [],
                linkList: [],
                loading: a,
                skeleton: d,
                actionType: {
                  FETCH: "@\u002Fview\u002Fsearch\u002FFETCH",
                  FETCH_MORE: "@\u002Fview\u002Fsearch\u002FFETCH_MORE",
                  RESET: "@\u002Fview\u002Fsearch\u002FRESET",
                },
              },
              columnIndex: {
                list: {
                  pageSize: h,
                  page: g,
                  total: b,
                  pointer: c,
                  lastPointer: c,
                  list: [],
                  loading: a,
                  error: c,
                  canPrev: d,
                  canNext: d,
                  linkList: [],
                  lastFetchOnServer: a,
                  actionType: {
                    UPDATE:
                      "@\u002Fview\u002FcolumnIndex\u002Flist\u002FUPDATE",
                    FETCH: "@\u002Fview\u002FcolumnIndex\u002Flist\u002FFETCH",
                    FORCE_FETCH:
                      "@\u002Fview\u002FcolumnIndex\u002Flist\u002FFORCE_FETCH",
                    FETCH_MORE:
                      "@\u002Fview\u002FcolumnIndex\u002Flist\u002FFETCH_MORE",
                    RESET: "@\u002Fview\u002FcolumnIndex\u002Flist\u002FRESET",
                  },
                  sort: o,
                  category: "all",
                },
                hotList: {
                  pageSize: h,
                  page: g,
                  total: b,
                  pointer: c,
                  lastPointer: c,
                  list: [],
                  loading: a,
                  error: c,
                  canPrev: d,
                  canNext: d,
                  linkList: [],
                  lastFetchOnServer: a,
                  actionType: {
                    UPDATE:
                      "@\u002Fview\u002FcolumnIndex\u002FhotList\u002FUPDATE",
                    FETCH:
                      "@\u002Fview\u002FcolumnIndex\u002FhotList\u002FFETCH",
                    FORCE_FETCH:
                      "@\u002Fview\u002FcolumnIndex\u002FhotList\u002FFORCE_FETCH",
                    FETCH_MORE:
                      "@\u002Fview\u002FcolumnIndex\u002FhotList\u002FFETCH_MORE",
                    RESET:
                      "@\u002Fview\u002FcolumnIndex\u002FhotList\u002FRESET",
                  },
                },
              },
              timelineIndex: {
                tdkTemplates: [],
                categoryNavList: [],
                tagNavList: [],
                splitTagList: [],
                timelineAdList: [],
                list: [],
                sort: r,
                category: l,
                categoryId: e,
                tagId: e,
                tag: "全部",
                actionType: {
                  FETCH_TIMELINE_LIST:
                    "@\u002Fview\u002FtimelineIndex\u002FFETCH_TIMELINE_LIST",
                  FETCH_CATEGORY_LIST:
                    "@\u002Fview\u002FtimelineIndex\u002FFETCH_CATEGORY_LIST",
                  FETCH_TAG_LIST:
                    "@\u002Fview\u002FtimelineIndex\u002FFETCH_TAG_LIST",
                  DELETE_ENTRY:
                    "@\u002Fview\u002FtimelineIndex\u002FDELETE_ENTRY",
                  DELETE_USER_ENTRIES:
                    "@\u002Fview\u002FtimelineIndex\u002FDELETE_USER_ENTRIES",
                  DELETE_TAG_ENTRIES:
                    "@\u002Fview\u002FtimelineIndex\u002FDELETE_TAG_ENTRIES",
                  FETCH_MORE: "@\u002Fview\u002FtimelineIndex\u002FFETCH_MORE",
                  FETCH: "@\u002Fview\u002FtimelineIndex\u002FFETCH",
                  RESET: "@\u002Fview\u002FtimelineIndex\u002FRESET",
                },
                serverRenderTimelineList: a,
                timelineList: {
                  list: [],
                  cursor: f,
                  skeleton: d,
                  loading: a,
                  hasMore: d,
                  categoryId: e,
                  tagId: e,
                  sort: e,
                  actionType: {
                    UPDATE_STATE: "timeline-list\u002FUPDATE_STATE",
                    FETCH_MORE: "timeline-list\u002FFETCH_MORE",
                    FETCH: "timeline-list\u002FFETCH",
                    RESET: "timeline-list\u002FRESET",
                  },
                },
                recommendList: {
                  list: [],
                  cursor: f,
                  loading: a,
                  skeleton: d,
                  hasMore: d,
                  actionType: {
                    UPDATE_STATE: "recommend-list\u002FUPDATE_STATE",
                    FETCH_MORE: "recommend-list\u002FFETCH_MORE",
                    FETCH: "recommend-list\u002FFETCH",
                    RESET: "recommend-list\u002FRESET",
                  },
                },
                followingList: {
                  list: [],
                  cursor: f,
                  skeleton: d,
                  loading: a,
                  hasMore: d,
                  actionType: {
                    UPDATE_STATE: "following-list\u002FUPDATE_STATE",
                    FETCH_MORE: "following-list\u002FFETCH_MORE",
                    FETCH: "following-list\u002FFETCH",
                    RESET: "following-list\u002FRESET",
                  },
                },
              },
              subscribe: {
                subscribed: {
                  list: [],
                  cursor: f,
                  skeleton: d,
                  loading: a,
                  hasMore: a,
                  actionType: {
                    UPDATE_STATE:
                      "view\u002Fsubscribe\u002Fsubscribed\u002Flist\u002FUPDATE_STATE",
                    FETCH_MORE:
                      "view\u002Fsubscribe\u002Fsubscribed\u002Flist\u002FFETCH_MORE",
                    FETCH:
                      "view\u002Fsubscribe\u002Fsubscribed\u002Flist\u002FFETCH",
                    RESET:
                      "view\u002Fsubscribe\u002Fsubscribed\u002Flist\u002FRESET",
                  },
                },
                all: {
                  list: [],
                  cursor: f,
                  loading: a,
                  skeleton: d,
                  hasMore: a,
                  linkList: e,
                  actionType: {
                    UPDATE_STATE:
                      "view\u002Fsubscribe\u002Fall\u002Flist\u002FUPDATE_STATE",
                    FETCH_MORE:
                      "view\u002Fsubscribe\u002Fall\u002Flist\u002FFETCH_MORE",
                    FETCH: "view\u002Fsubscribe\u002Fall\u002Flist\u002FFETCH",
                    RESET: "view\u002Fsubscribe\u002Fall\u002Flist\u002FRESET",
                  },
                },
              },
              entryPublic: {
                entry: { user: {} },
                relatedEntryList: [],
                relatedCollectionList: [],
                actionType: {
                  FETCH: "@\u002Fview\u002FentryPublic\u002FFETCH",
                  RESET: "@\u002Fview\u002FentryPublic\u002FRESET",
                },
              },
              user: {
                user: {},
                serverRendered: a,
                userAnnuals: [],
                actionType: {
                  FETCH: "@\u002Fview\u002Fuser\u002FFETCH",
                  RESET: "@\u002Fview\u002Fuser\u002FRESET",
                  UPDATE: "@\u002Fview\u002Fuser\u002FUPDATE",
                  FETCH_ANNUALS: "@\u002Fview\u002Fuser\u002FFETCH_ANNUALS",
                },
                detailList: {
                  actionType: {
                    RESET: "@\u002Fview\u002Fuser\u002FdetailList\u002FRESET",
                  },
                  likeList: {
                    list: [],
                    cursor: f,
                    hasMore: a,
                    loading: a,
                    skeleton: d,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FlikePostList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FlikePostList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FlikePostList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FlikePostList\u002FRESET",
                    },
                  },
                  postList: {
                    list: [],
                    hasMore: a,
                    skeleton: a,
                    loading: a,
                    sort: o,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpostList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpostList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpostList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpostList\u002FRESET",
                    },
                  },
                  searchList: {
                    list: [],
                    hasMore: a,
                    skeleton: a,
                    loading: a,
                    key_word: e,
                    search_type: b,
                    cursor: f,
                    isPostSearch: a,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FsearchList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FsearchList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FsearchList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FsearchList\u002FRESET",
                    },
                  },
                  tagList: {
                    list: [],
                    loading: a,
                    skeleton: d,
                    hasMore: a,
                    cursor: f,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FtagList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FtagList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FtagList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FtagList\u002FRESET",
                    },
                  },
                  collectionList: {
                    list: [],
                    userId: e,
                    skeleton: d,
                    hasMore: a,
                    cursor: f,
                    type: "created",
                    loading: a,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcollectionList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcollectionList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcollectionList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcollectionList\u002FRESET",
                      TOGGLE_FOLLOW_COLLECTION:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcollectionList\u002FTOGGLE_FOLLOW_COLLECTION",
                      FOLLOW_COLLECTION:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcollectionList\u002FFOLLOW_COLLECTION",
                      UNFOLLOW_COLLECTION:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcollectionList\u002FUNFOLLOW_COLLECTION",
                      DELELTE_COLLECTION:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcollectionList\u002FDELELTE_COLLECTION",
                      ADD_COLLECTION:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcollectionList\u002FADD_COLLECTION",
                      EDIT_COLLECTION:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcollectionList\u002FEDIT_COLLECTION",
                    },
                  },
                  followerList: {
                    list: [],
                    cursor: f,
                    hasMore: a,
                    loading: a,
                    skeleton: a,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowerList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowerList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowerList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowerList\u002FRESET",
                    },
                  },
                  followingList: {
                    list: [],
                    cursor: f,
                    hasMore: a,
                    skeleton: a,
                    loading: a,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowingList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowingList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowingList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowingList\u002FRESET",
                    },
                  },
                  followingTeamsList: {
                    list: [],
                    cursor: f,
                    hasMore: a,
                    skeleton: a,
                    loading: a,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowingTeamsList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowingTeamsList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowingTeamsList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FfollowingTeamsList\u002FRESET",
                    },
                  },
                  activityList: {
                    list: [],
                    cursor: f,
                    hasMore: a,
                    loading: a,
                    skeleton: a,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FactivityList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FactivityList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FactivityList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FactivityList\u002FRESET",
                    },
                  },
                  bookList: {
                    list: [],
                    cursor: f,
                    skeleton: d,
                    hasMore: a,
                    loading: a,
                    type: "wrote",
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FbookList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FbookList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FbookList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FbookList\u002FRESET",
                    },
                  },
                  pinList: {
                    list: [],
                    hasMore: a,
                    loading: a,
                    skeleton: d,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpinList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpinList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpinList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpinList\u002FRESET",
                    },
                  },
                  courseList: {
                    list: [],
                    hasMore: a,
                    loading: a,
                    skeleton: d,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcourseList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcourseList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcourseList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcourseList\u002FRESET",
                    },
                  },
                  pinPraisedList: {
                    list: [],
                    cursor: f,
                    hasMore: a,
                    loading: a,
                    skeleton: d,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpinPraisedList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpinPraisedList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpinPraisedList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FpinPraisedList\u002FRESET",
                    },
                  },
                  eventList: {
                    list: [],
                    cursor: f,
                    hasMore: a,
                    loading: a,
                    skeleton: a,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FeventList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FeventList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FeventList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FeventList\u002FRESET",
                    },
                  },
                  selfColumnList: {
                    list: [],
                    hasMore: a,
                    skeleton: a,
                    loading: a,
                    cursor: f,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcolumnList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcolumnList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcolumnList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcolumnList\u002FRESET",
                    },
                  },
                  columnFollowedList: {
                    list: [],
                    hasMore: a,
                    skeleton: a,
                    loading: a,
                    cursor: f,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcolumnFollowedList\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcolumnFollowedList\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcolumnFollowedList\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcolumnFollowedList\u002FRESET",
                      FILTER:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002FcolumnFollowedList\u002FFILTER",
                    },
                  },
                  realtimes: {
                    list: [],
                    cursor: f,
                    hasMore: a,
                    loading: a,
                    skeleton: a,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002Frealtimes\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002Frealtimes\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002Frealtimes\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002Frealtimes\u002FRESET",
                      DELETE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002Frealtimes\u002FDELETE",
                    },
                  },
                  realtimeliked: {
                    list: [],
                    cursor: f,
                    hasMore: a,
                    loading: a,
                    skeleton: a,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002Frealtimeliked\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002Frealtimeliked\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002Frealtimeliked\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002Frealtimeliked\u002FRESET",
                      DELETE:
                        "@\u002Fview\u002Fuser\u002FdetailList\u002Frealtimeliked\u002FDELETE",
                    },
                  },
                },
              },
              tag: {
                tag: {},
                actionType: {
                  FETCH: "@\u002Fview\u002Ftag\u002FFETCH",
                  FETCH_LIST: "@\u002Fview\u002Ftag\u002FFETCH_LIST",
                  RESET: "@\u002Fview\u002Ftag\u002FRESET",
                },
                list: {
                  list: [],
                  cursor: f,
                  loading: a,
                  skeleton: a,
                  hasMore: a,
                  actionType: {
                    UPDATE_STATE:
                      "@\u002Fview\u002Ftag\u002Flist\u002FUPDATE_STATE",
                    FETCH_MORE:
                      "@\u002Fview\u002Ftag\u002Flist\u002FFETCH_MORE",
                    FETCH: "@\u002Fview\u002Ftag\u002Flist\u002FFETCH",
                    RESET: "@\u002Fview\u002Ftag\u002Flist\u002FRESET",
                  },
                },
              },
              notification: {
                user: {
                  actionType: {
                    READ_ALL:
                      "@\u002Fview\u002Fnotification\u002Fuser\u002FREAD_ALL",
                    RESET: "@\u002Fview\u002Fnotification\u002Fuser\u002FRESET",
                  },
                  listState: {
                    list: [],
                    cursor: f,
                    hasMore: a,
                    isLoading: a,
                    messageType: 3,
                    msgTotal: b,
                    msgSubMap: { 1: b, 2: b, 3: b, 4: b, 7: b },
                  },
                  list: {
                    pageSize: h,
                    page: g,
                    total: b,
                    pointer: c,
                    lastPointer: c,
                    list: [],
                    loading: a,
                    error: c,
                    canPrev: d,
                    canNext: d,
                    linkList: [],
                    lastFetchOnServer: a,
                    actionType: {
                      UPDATE:
                        "@\u002Fview\u002Fnotification\u002Fuser\u002Flist\u002FUPDATE",
                      FETCH:
                        "@\u002Fview\u002Fnotification\u002Fuser\u002Flist\u002FFETCH",
                      FORCE_FETCH:
                        "@\u002Fview\u002Fnotification\u002Fuser\u002Flist\u002FFORCE_FETCH",
                      FETCH_MORE:
                        "@\u002Fview\u002Fnotification\u002Fuser\u002Flist\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fnotification\u002Fuser\u002Flist\u002FRESET",
                    },
                  },
                },
                system: {
                  actionType: {
                    READ_ALL:
                      "@\u002Fview\u002Fnotification\u002Fsystem\u002FREAD_ALL",
                    RESET:
                      "@\u002Fview\u002Fnotification\u002Fsystem\u002FRESET",
                  },
                  list: {
                    pageSize: h,
                    page: g,
                    total: b,
                    pointer: c,
                    lastPointer: c,
                    list: [],
                    loading: a,
                    error: c,
                    canPrev: d,
                    canNext: d,
                    linkList: [],
                    lastFetchOnServer: a,
                    actionType: {
                      UPDATE:
                        "@\u002Fview\u002Fnotification\u002Fsystem\u002Flist\u002FUPDATE",
                      FETCH:
                        "@\u002Fview\u002Fnotification\u002Fsystem\u002Flist\u002FFETCH",
                      FORCE_FETCH:
                        "@\u002Fview\u002Fnotification\u002Fsystem\u002Flist\u002FFORCE_FETCH",
                      FETCH_MORE:
                        "@\u002Fview\u002Fnotification\u002Fsystem\u002Flist\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fnotification\u002Fsystem\u002Flist\u002FRESET",
                    },
                  },
                },
              },
              column: {
                serverRenderList: a,
                column: { id: m },
                entry: {
                  isCache: d,
                  id: m,
                  screenshot: p,
                  liked: a,
                  article_id: m,
                  article_info: {
                    article_id: m,
                    user_id: A,
                    category_id: "6809637767543259144",
                    tag_ids: [
                      6809640398105870000, 6809640369764958000,
                      6809640407484334000,
                    ],
                    visible_level: b,
                    link_url: e,
                    cover_image:
                      "https:\u002F\u002Fp3-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002F4cf0e7b553704152a23879301ed0c58c~tplv-k3u1fbpfcp-watermark.image",
                    is_gfw: b,
                    title: B,
                    brief_content: C,
                    is_english: b,
                    is_original: g,
                    user_index: b,
                    original_type: b,
                    original_author: e,
                    content: e,
                    ctime: "1618192701",
                    mtime: "1645489487",
                    rtime: "1618198314",
                    draft_id: D,
                    view_count: E,
                    collect_count: F,
                    digg_count: s,
                    comment_count: G,
                    hot_index: 2463,
                    is_hot: b,
                    rank_index: 0.00781208,
                    status: i,
                    verify_status: g,
                    audit_status: i,
                    mark_content:
                      "---\ntheme: cyanosis\nhighlight: androidstudio\n---\n\n**当学习成为了习惯，知识也就变成了常识。** 感谢各位的 **点赞**、**收藏**和**评论**。\n\n新视频和文章会第一时间在微信公众号发送，欢迎关注：[李永宁lyn](https:\u002F\u002Fgitee.com\u002Fliyongning\u002Ftypora-image-bed\u002Fraw\u002Fmaster\u002F202202171742614.jpg)\n\n文章已收录到 [github](https:\u002F\u002Fgithub.com\u002Fliyongning\u002Fblog)，欢迎 Watch 和 Star。\n\n# 目标\n\n深入理解 Vue 的初始化过程，再也不怕 **面试官** 的那道面试题：`new Vue(options)` 发生了什么？\n\n# 找入口\n\n想知道 `new Vue(options)` 都做了什么，就得先找到 Vue 的构造函数是在哪声明的，有两个办法：\n\n* 从 rollup 配置文件中找到编译的入口，然后一步步找到 Vue 构造函数，这种方式 **费劲**\n\n* 通过编写示例代码，然后打断点的方式，一步到位，**简单**\n\n我们就采用第二种方式，写示例，打断点，一步到位。\n\n* 在 `\u002Fexamples` 目录下增加一个示例文件 —— `test.html`，在文件中添加如下内容：\n\n```html\n\u003C!DOCTYPE html\u003E\n\u003Chtml lang=\"en\"\u003E\n\u003Chead\u003E\n  \u003Cmeta charset=\"UTF-8\"\u003E\n  \u003Ctitle\u003EVue 源码解读\u003C\u002Ftitle\u003E\n\u003C\u002Fhead\u003E\n\u003Cbody\u003E\n  \u003Cdiv id=\"app\"\u003E\n    {{ msg }}\n  \u003C\u002Fdiv\u003E\n  \u003Cscript src=\"..\u002Fdist\u002Fvue.js\"\u003E\u003C\u002Fscript\u003E\n  \u003Cscript\u003E\n    debugger\n    new Vue({\n      el: '#app',\n      data: {\n        msg: 'hello vue'\n      }\n    })\n  \u003C\u002Fscript\u003E\n\u003C\u002Fbody\u003E\n\u003C\u002Fhtml\u003E\n```\n* 在浏览器中打开控制台，然后打开 `test.html`，则会进入断点调试，然后找到 Vue 构造函数所在的文件\n\n![Mar-26-2021 08-30-52.gif](https:\u002F\u002Fp1-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002Fd839ea6f3e5d4adcaf1ea9a8f6ff1a70~tplv-k3u1fbpfcp-watermark.image)\n\n得到 Vue 构造函数在 `\u002Fsrc\u002Fcore\u002Finstance\u002Findex.js` 文件中，接下来正式开始源码阅读，带着目标去阅读。\n\n\u003E 在阅读过程中如遇到看不明白的地方，可通过编写示例代码，然后使用浏览器的调试功能进行一步步调试，配合理解，如果还是理解不了，就做个备注继续向后看，也许你看到其它地方，就突然明白这个地方在做什么，或者回头再来看，就会懂了，源码这个东西，一定要多看，要想精通，一遍两遍肯定是不够的\n\n# 源码解读 —— Vue 初始化过程\n\n## Vue\n\n\u003E \u002Fsrc\u002Fcore\u002Finstance\u002Findex.js\n\n```javascript\nimport { initMixin } from '.\u002Finit'\n\n\u002F\u002F Vue 构造函数\nfunction Vue (options) {\n  \u002F\u002F 调用 Vue.prototype._init 方法，该方法是在 initMixin 中定义的\n  this._init(options)\n}\n\n\u002F\u002F 定义 Vue.prototype._init 方法\ninitMixin(Vue)\n\nexport default Vue\n```\n\n## Vue.prototype._init\n\n\u003E \u002Fsrc\u002Fcore\u002Finstance\u002Finit.js\n\n```javascript\n\u002F**\n * 定义 Vue.prototype._init 方法 \n * @param {*} Vue Vue 构造函数\n *\u002F\nexport function initMixin (Vue: Class\u003CComponent\u003E) {\n  \u002F\u002F 负责 Vue 的初始化过程\n  Vue.prototype._init = function (options?: Object) {\n    \u002F\u002F vue 实例\n    const vm: Component = this\n    \u002F\u002F 每个 vue 实例都有一个 _uid，并且是依次递增的\n    vm._uid = uid++\n\n    \u002F\u002F a flag to avoid this being observed\n    vm._isVue = true\n    \u002F\u002F 处理组件配置项\n    if (options && options._isComponent) {\n      \u002F**\n       * 每个子组件初始化时走这里，这里只做了一些性能优化\n       * 将组件配置对象上的一些深层次属性放到 vm.$options 选项中，以提高代码的执行效率\n       *\u002F\n      initInternalComponent(vm, options)\n    } else {\n      \u002F**\n       * 初始化根组件时走这里，合并 Vue 的全局配置到根组件的局部配置，比如 Vue.component 注册的全局组件会合并到 根实例的 components 选项中\n       * 至于每个子组件的选项合并则发生在两个地方：\n       *   1、Vue.component 方法注册的全局组件在注册时做了选项合并\n       *   2、{ components: { xx } } 方式注册的局部组件在执行编译器生成的 render 函数时做了选项合并，包括根组件中的 components 配置\n       *\u002F\n      vm.$options = mergeOptions(\n        resolveConstructorOptions(vm.constructor),\n        options || {},\n        vm\n      )\n    }\n    \u002F* istanbul ignore else *\u002F\n    if (process.env.NODE_ENV !== 'production') {\n      \u002F\u002F 设置代理，将 vm 实例上的属性代理到 vm._renderProxy\n      initProxy(vm)\n    } else {\n      vm._renderProxy = vm\n    }\n    \u002F\u002F expose real self\n    vm._self = vm\n    \u002F\u002F 初始化组件实例关系属性，比如 $parent、$children、$root、$refs 等\n    initLifecycle(vm)\n    \u002F**\n     * 初始化自定义事件，这里需要注意一点，所以我们在 \u003Ccomp @click=\"handleClick\" \u002F\u003E 上注册的事件，监听者不是父组件，\n     * 而是子组件本身，也就是说事件的派发和监听者都是子组件本身，和父组件无关\n     *\u002F\n    initEvents(vm)\n    \u002F\u002F 解析组件的插槽信息，得到 vm.$slot，处理渲染函数，得到 vm.$createElement 方法，即 h 函数\n    initRender(vm)\n    \u002F\u002F 调用 beforeCreate 钩子函数\n    callHook(vm, 'beforeCreate')\n    \u002F\u002F 初始化组件的 inject 配置项，得到 result[key] = val 形式的配置对象，然后对结果数据进行响应式处理，并代理每个 key 到 vm 实例\n    initInjections(vm) \u002F\u002F resolve injections before data\u002Fprops\n    \u002F\u002F 数据响应式的重点，处理 props、methods、data、computed、watch\n    initState(vm)\n    \u002F\u002F 解析组件配置项上的 provide 对象，将其挂载到 vm._provided 属性上\n    initProvide(vm) \u002F\u002F resolve provide after data\u002Fprops\n    \u002F\u002F 调用 created 钩子函数\n    callHook(vm, 'created')\n\n    \u002F\u002F 如果发现配置项上有 el 选项，则自动调用 $mount 方法，也就是说有了 el 选项，就不需要再手动调用 $mount，反之，没有 el 则必须手动调用 $mount\n    if (vm.$options.el) {\n      \u002F\u002F 调用 $mount 方法，进入挂载阶段\n      vm.$mount(vm.$options.el)\n    }\n  }\n}\n\n```\n\n## resolveConstructorOptions\n\n\u003E \u002Fsrc\u002Fcore\u002Finstance\u002Finit.js\n\n```javascript\n\u002F**\n * 从组件构造函数中解析配置对象 options，并合并基类选项\n * @param {*} Ctor \n * @returns \n *\u002F\nexport function resolveConstructorOptions (Ctor: Class\u003CComponent\u003E) {\n  \u002F\u002F 配置项目\n  let options = Ctor.options\n  if (Ctor.super) {\n    \u002F\u002F 存在基类，递归解析基类构造函数的选项\n    const superOptions = resolveConstructorOptions(Ctor.super)\n    const cachedSuperOptions = Ctor.superOptions\n    if (superOptions !== cachedSuperOptions) {\n      \u002F\u002F 说明基类构造函数选项已经发生改变，需要重新设置\n      Ctor.superOptions = superOptions\n      \u002F\u002F 检查 Ctor.options 上是否有任何后期修改\u002F附加的选项（＃4976）\n      const modifiedOptions = resolveModifiedOptions(Ctor)\n      \u002F\u002F 如果存在被修改或增加的选项，则合并两个选项\n      if (modifiedOptions) {\n        extend(Ctor.extendOptions, modifiedOptions)\n      }\n      \u002F\u002F 选项合并，将合并结果赋值为 Ctor.options\n      options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)\n      if (options.name) {\n        options.components[options.name] = Ctor\n      }\n    }\n  }\n  return options\n}\n\n```\n\n## resolveModifiedOptions\n\n\u003E \u002Fsrc\u002Fcore\u002Finstance\u002Finit.js\n\n```javascript\n\u002F**\n * 解析构造函数选项中后续被修改或者增加的选项\n *\u002F\nfunction resolveModifiedOptions (Ctor: Class\u003CComponent\u003E): ?Object {\n  let modified\n  \u002F\u002F 构造函数选项\n  const latest = Ctor.options\n  \u002F\u002F 密封的构造函数选项，备份\n  const sealed = Ctor.sealedOptions\n  \u002F\u002F 对比两个选项，记录不一致的选项\n  for (const key in latest) {\n    if (latest[key] !== sealed[key]) {\n      if (!modified) modified = {}\n      modified[key] = latest[key]\n    }\n  }\n  return modified\n}\n\n```\n\n## mergeOptions\n\n\u003E \u002Fsrc\u002Fcore\u002Futil\u002Foptions.js\n\n```javascript\n\u002F**\n * 合并两个选项，出现相同配置项时，子选项会覆盖父选项的配置\n *\u002F\nexport function mergeOptions (\n  parent: Object,\n  child: Object,\n  vm?: Component\n): Object {\n  if (process.env.NODE_ENV !== 'production') {\n    checkComponents(child)\n  }\n\n  if (typeof child === 'function') {\n    child = child.options\n  }\n\n  \u002F\u002F 标准化 props、inject、directive 选项，方便后续程序的处理\n  normalizeProps(child, vm)\n  normalizeInject(child, vm)\n  normalizeDirectives(child)\n\n  \u002F\u002F 处理原始 child 对象上的 extends 和 mixins，分别执行 mergeOptions，将这些继承而来的选项合并到 parent\n  \u002F\u002F mergeOptions 处理过的对象会含有 _base 属性\n  if (!child._base) {\n    if (child.extends) {\n      parent = mergeOptions(parent, child.extends, vm)\n    }\n    if (child.mixins) {\n      for (let i = 0, l = child.mixins.length; i \u003C l; i++) {\n        parent = mergeOptions(parent, child.mixins[i], vm)\n      }\n    }\n  }\n\n  const options = {}\n  let key\n  \u002F\u002F 遍历 父选项\n  for (key in parent) {\n    mergeField(key)\n  }\n\n  \u002F\u002F 遍历 子选项，如果父选项不存在该配置，则合并，否则跳过，因为父子拥有同一个属性的情况在上面处理父选项时已经处理过了，用的子选项的值\n  for (key in child) {\n    if (!hasOwn(parent, key)) {\n      mergeField(key)\n    }\n  }\n\n  \u002F\u002F 合并选项，childVal 优先级高于 parentVal\n  function mergeField (key) {\n    \u002F\u002F strats = Object.create(null)\n    const strat = strats[key] || defaultStrat\n    \u002F\u002F 值为如果 childVal 存在则优先使用 childVal，否则使用 parentVal\n    options[key] = strat(parent[key], child[key], vm, key)\n  }\n  return options\n}\n\n```\n\n## initInjections\n\n\u003E \u002Fsrc\u002Fcore\u002Finstance\u002Finject.js\n\n```javascript\n\u002F**\n * 初始化 inject 配置项\n *   1、得到 result[key] = val\n *   2、对结果数据进行响应式处理，代理每个 key 到 vm 实例\n *\u002F\nexport function initInjections (vm: Component) {\n  \u002F\u002F 解析 inject 配置项，然后从祖代组件的配置中找到 配置项中每一个 key 对应的 val，最后得到 result[key] = val 的结果\n  const result = resolveInject(vm.$options.inject, vm)\n  \u002F\u002F 对 result 做 数据响应式处理，也有代理 inject 配置中每个 key 到 vm 实例的作用。\n  \u002F\u002F 不不建议在子组件去更改这些数据，因为一旦祖代组件中 注入的 provide 发生更改，你在组件中做的更改就会被覆盖\n  if (result) {\n    toggleObserving(false)\n    Object.keys(result).forEach(key =\u003E {\n      \u002F* istanbul ignore else *\u002F\n      if (process.env.NODE_ENV !== 'production') {\n        defineReactive(vm, key, result[key], () =\u003E {\n          warn(\n            `Avoid mutating an injected value directly since the changes will be ` +\n            `overwritten whenever the provided component re-renders. ` +\n            `injection being mutated: \"${key}\"`,\n            vm\n          )\n        })\n      } else {\n        defineReactive(vm, key, result[key])\n      }\n    })\n    toggleObserving(true)\n  }\n}\n\n```\n\n## resolveInject\n\n\u003E \u002Fsrc\u002Fcore\u002Finstance\u002Finject.js\n\n```javascript\n\u002F**\n * 解析 inject 配置项，从祖代组件的 provide 配置中找到 key 对应的值，否则用 默认值，最后得到 result[key] = val\n * inject 对象肯定是以下这个结构，因为在 合并 选项时对组件配置对象做了标准化处理\n * @param {*} inject = {\n *  key: {\n *    from: provideKey,\n *    default: xx\n *  }\n * }\n *\u002F\nexport function resolveInject (inject: any, vm: Component): ?Object {\n  if (inject) {\n    \u002F\u002F inject is :any because flow is not smart enough to figure out cached\n    const result = Object.create(null)\n    \u002F\u002F inject 配置项的所有的 key\n    const keys = hasSymbol\n      ? Reflect.ownKeys(inject)\n      : Object.keys(inject)\n\n    \u002F\u002F 遍历 key\n    for (let i = 0; i \u003C keys.length; i++) {\n      const key = keys[i]\n      \u002F\u002F 跳过 __ob__ 对象\n      \u002F\u002F #6574 in case the inject object is observed...\n      if (key === '__ob__') continue\n      \u002F\u002F 拿到 provide 中对应的 key\n      const provideKey = inject[key].from\n      let source = vm\n      \u002F\u002F 遍历所有的祖代组件，直到 根组件，找到 provide 中对应 key 的值，最后得到 result[key] = provide[provideKey]\n      while (source) {\n        if (source._provided && hasOwn(source._provided, provideKey)) {\n          result[key] = source._provided[provideKey]\n          break\n        }\n        source = source.$parent\n      }\n      \u002F\u002F 如果上一个循环未找到，则采用 inject[key].default，如果没有设置 default 值，则抛出错误\n      if (!source) {\n        if ('default' in inject[key]) {\n          const provideDefault = inject[key].default\n          result[key] = typeof provideDefault === 'function'\n            ? provideDefault.call(vm)\n            : provideDefault\n        } else if (process.env.NODE_ENV !== 'production') {\n          warn(`Injection \"${key}\" not found`, vm)\n        }\n      }\n    }\n    return result\n  }\n}\n\n```\n\n## initProvide\n\n\u003E \u002Fsrc\u002Fcore\u002Finstance\u002Finject.js\n\n```javascript\n\u002F**\n * 解析组件配置项上的 provide 对象，将其挂载到 vm._provided 属性上 \n *\u002F\nexport function initProvide (vm: Component) {\n  const provide = vm.$options.provide\n  if (provide) {\n    vm._provided = typeof provide === 'function'\n      ? provide.call(vm)\n      : provide\n  }\n}\n\n```\n\n# 总结\n\nVue 的初始化过程（new Vue(options)）都做了什么？\n\n* 处理组件配置项\n\n  * 初始化根组件时进行了选项合并操作，将全局配置合并到根组件的局部配置上\n  \n  * 初始化每个子组件时做了一些性能优化，将组件配置对象上的一些深层次属性放到 vm.$options 选项中，以提高代码的执行效率\n  \n* 初始化组件实例的关系属性，比如 \\$parent、\\$children、\\$root、\\$refs 等\n\n* 处理自定义事件\n\n* 调用 beforeCreate 钩子函数\n\n* 初始化组件的 inject 配置项，得到 `ret[key] = val` 形式的配置对象，然后对该配置对象进行浅层的响应式处理（只处理了对象第一层数据），并代理每个 key 到 vm 实例上\n\n* 数据响应式，处理 props、methods、data、computed、watch 等选项\n\n* 解析组件配置项上的 provide 对象，将其挂载到 vm._provided 属性上\n\n* 调用 created 钩子函数\n\n* 如果发现配置项上有 el 选项，则自动调用 \\$mount 方法，也就是说有了 el 选项，就不需要再手动调用 \\$mount 方法，反之，没提供 el 选项则必须调用 \\$mount\n\n* 接下来则进入挂载阶段\n\n# 链接\n\n* [配套视频，关注微信公众号回复](https:\u002F\u002Fgitee.com\u002Fliyongning\u002Ftypora-image-bed\u002Fraw\u002Fmaster\u002F202202171742614.jpg)：\"精通 Vue 技术栈源码原理视频版\" 获取\n\n* [精通 Vue 技术栈源码原理 专栏](https:\u002F\u002Fmp.weixin.qq.com\u002Fmp\u002Fappmsgalbum?__biz=MzA3NTk4NjQ1OQ==&action=getalbum&album_id=2273541436891693065#wechat_redirect)\n\n* [github 仓库 liyongning\u002FVue](https:\u002F\u002Fgithub.com\u002Fliyongning\u002FVue) 欢迎 Star\n\n\n\n感谢各位的：**点赞**、**收藏**和**评论**，我们下期见。\n\n***\n\n**当学习成为了习惯，知识也就变成了常识。** 感谢各位的 **点赞**、**收藏**和**评论**。\n\n新视频和文章会第一时间在微信公众号发送，欢迎关注：[李永宁lyn](https:\u002F\u002Fgitee.com\u002Fliyongning\u002Ftypora-image-bed\u002Fraw\u002Fmaster\u002F202202171742614.jpg)\n\n文章已收录到 [github 仓库 liyongning\u002Fblog](https:\u002F\u002Fgithub.com\u002Fliyongning\u002Fblog)，欢迎 Watch 和 Star。\n",
                    display_count: b,
                    is_markdown: g,
                    app_html_content: e,
                  },
                  author_user_info: {
                    user_id: A,
                    user_name: H,
                    company: "B 站搜：李永宁_lyn",
                    job_title: "微信搜：李永宁lyn",
                    avatar_large:
                      "https:\u002F\u002Fp9-passport.byteacctimg.com\u002Fimg\u002Fuser-avatar\u002Fecfb3bbd73753344105b06067757a70a~300x300.image",
                    level: t,
                    description: "http:\u002F\u002Fgithub.com\u002Fliyongning",
                    followee_count: 21,
                    follower_count: 5247,
                    post_article_count: 70,
                    digg_article_count: 76,
                    got_digg_count: 6253,
                    got_view_count: 600619,
                    post_shortmsg_count: 30,
                    digg_shortmsg_count: 19,
                    isfollowed: a,
                    favorable_author: g,
                    power: I,
                    study_point: b,
                    university: { university_id: f, name: e, logo: e },
                    major: { major_id: f, parent_id: f, name: e },
                    student_status: b,
                    select_event_count: b,
                    select_online_course_count: b,
                    identity: b,
                    is_select_annual: d,
                    select_annual_rank: b,
                    annual_list_type: b,
                    extraMap: {},
                    is_logout: b,
                    annual_info: [],
                    account_amount: b,
                    user_growth_info: {
                      user_id: 1028798616461326,
                      jpower: I,
                      jscore: 513.7,
                      jpower_level: t,
                      jscore_level: t,
                      jscore_title: "先锋掘友",
                      author_achievement_list: [g],
                      vip_level: b,
                      vip_title: e,
                      jscore_next_level_score: 2000,
                      jscore_this_level_mini_score: 500,
                    },
                    is_vip: a,
                    become_author_days: b,
                    collection_set_article_count: b,
                    recommend_article_count_daily: b,
                    article_collect_count_daily: b,
                  },
                  category: {
                    category_id: "6809637767543259144",
                    category_name: "前端",
                    category_url: "frontend",
                    rank: i,
                    back_ground:
                      "https:\u002F\u002Flc-mhke0kuv.cn-n1.lcfile.com\u002F8c95587526f346c0.png",
                    icon: "https:\u002F\u002Flc-mhke0kuv.cn-n1.lcfile.com\u002F1c40f5eaba561e32.png",
                    ctime: 1457483942,
                    mtime: 1432503190,
                    show_type: 3,
                    item_type: i,
                    promote_tag_cap: 4,
                    promote_priority: i,
                    id: "6809637767543259144",
                    name: "前端",
                    title: "前端",
                    alias: "frontend",
                  },
                  tags: [
                    {
                      entriesCount: p,
                      subscribed: a,
                      id: "6809640398105870343",
                      tag_id: "6809640398105870343",
                      tag_name: "JavaScript",
                      color: "#616161",
                      icon: "https:\u002F\u002Fp1-jj.byteimg.com\u002Ftos-cn-i-t2oaga2asx\u002Fleancloud-assets\u002F5d70fd6af940df373834.png~tplv-t2oaga2asx-image.image",
                      back_ground: e,
                      show_navi: b,
                      ctime: 1435884803,
                      mtime: 1679298931,
                      id_type: 9,
                      tag_alias: e,
                      post_article_count: 121069,
                      concern_user_count: 501200,
                      title: "JavaScript",
                      tagId: "6809640398105870343",
                      articleCount: 121069,
                      subscribersCount: 501200,
                      createdAt: c,
                      updatedAt: c,
                    },
                    {
                      entriesCount: p,
                      subscribed: a,
                      id: "6809640369764958215",
                      tag_id: "6809640369764958215",
                      tag_name: "Vue.js",
                      color: e,
                      icon: "https:\u002F\u002Fp1-jj.byteimg.com\u002Ftos-cn-i-t2oaga2asx\u002Fleancloud-assets\u002F7b5c3eb591b671749fee.png~tplv-t2oaga2asx-image.image",
                      back_ground: e,
                      show_navi: b,
                      ctime: 1432234520,
                      mtime: 1679298962,
                      id_type: 9,
                      tag_alias: "vue,Vue",
                      post_article_count: 54949,
                      concern_user_count: 407608,
                      title: "Vue.js",
                      tagId: "6809640369764958215",
                      articleCount: 54949,
                      subscribersCount: 407608,
                      createdAt: c,
                      updatedAt: c,
                    },
                    {
                      entriesCount: p,
                      subscribed: a,
                      id: "6809640407484334093",
                      tag_id: "6809640407484334093",
                      tag_name: "前端",
                      color: "#60ADFF",
                      icon: "https:\u002F\u002Fp1-jj.byteimg.com\u002Ftos-cn-i-t2oaga2asx\u002Fleancloud-assets\u002Fbac28828a49181c34110.png~tplv-t2oaga2asx-image.image",
                      back_ground: e,
                      show_navi: g,
                      ctime: 1435971546,
                      mtime: 1679299227,
                      id_type: 9,
                      tag_alias: e,
                      post_article_count: 342089,
                      concern_user_count: 639883,
                      title: "前端",
                      tagId: "6809640407484334093",
                      articleCount: 342089,
                      subscribersCount: 639883,
                      createdAt: c,
                      updatedAt: c,
                    },
                  ],
                  user_interact: {
                    id: 6950084496515400000,
                    omitempty: i,
                    user_id: b,
                    is_digg: a,
                    is_follow: a,
                    is_collect: a,
                    collect_set_count: b,
                  },
                  org: { org_info: c, org_user: c, is_followed: a },
                  req_id: "20230320160041DA8A3F018A736809236E",
                  status: { push_status: b },
                  author_interact: c,
                  extra: { boost_type: e },
                  title: B,
                  user: J,
                  viewCount: p,
                  commentsCount: G,
                  isEvent: p,
                  abstract: C,
                  latestCommentAt: c,
                  createdAt: new Date(1618192701000),
                  updatedAt: c,
                  isTopicEvent: a,
                  likedCount: s,
                  likeCount: s,
                  content: e,
                  originalUrl: e,
                  type: "post",
                  collected: a,
                  viewsCount: E,
                  username: H,
                  viewerHasLiked: a,
                  draftId: D,
                  collectionCount: F,
                },
                entryView: {},
                author: J,
                adEntryList: [],
                relatedEntryList: [],
                linkVotingList: [],
                userAnnuals: [],
                columnList: [],
                resultHtml:
                  '\u003Cstyle\u003E@charset "UTF-8";.markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:14px;overflow-x:hidden;color:var(--cyanosis-base-color);transition:color .35s;--cyanosis-base-color:#353535;--cyanosis-title-color:#005bb7;--cyanosis-strong-color:#2196f3;--cyanosis-em-color:#4fc3f7;--cyanosis-del-color:#ccc;--cyanosis-link-color:#3da8f5;--cyanosis-linkh-color:#007fff;--cyanosis-border-color:#bedcff;--cyanosis-border-color-2:#ececec;--cyanosis-bg-color:#fff;--cyanosis-blockquote-color:#8c8c8c;--cyanosis-blockquote-bg-color:#f0fdff;--cyanosis-code-color:#c2185b;--cyanosis-code-bg-color:#fff4f4;--cyanosis-code-pre-color:#f8f8f8;--cyanosis-table-border-color:#c3e0fd;--cyanosis-table-th-color:#dff0ff;--cyanosis-table-tht-color:#005bb7;--cyanosis-table-tr-nc-color:#f7fbff;--cyanosis-table-trh-color:#e0edf7;--cyanosis-slct-title-color:#005bb7;--cyanosis-slct-titlebg-color:rgba(175,207,247,0.25);--cyanosis-slct-text-color:#c80000;--cyanosis-slct-bg-color:rgba(175,207,247,0.25);--cyanosis-slct-del-color:#999;--cyanosis-slct-elbg-color:#e8ebec;--cyanosis-slct-codebg-color:#ffeaeb;--cyanosis-slct-prebg-color:rgba(160,200,255,0.25)}.markdown-body.__dark{--cyanosis-base-color:#cacaca;--cyanosis-title-color:#ddd;--cyanosis-strong-color:#fe9900;--cyanosis-em-color:#ffd28e;--cyanosis-del-color:#ccc;--cyanosis-link-color:#ffb648;--cyanosis-linkh-color:#fe9900;--cyanosis-border-color:#ffe3ba;--cyanosis-border-color-2:#ffcb7b;--cyanosis-bg-color:#2f2f2f;--cyanosis-blockquote-color:#c7c7c7;--cyanosis-blockquote-bg-color:rgba(255,199,116,0.1);--cyanosis-code-color:#000;--cyanosis-code-bg-color:#ffcb7b;--cyanosis-code-pre-color:rgba(255,227,185,0.5);--cyanosis-table-border-color:#fe9900;--cyanosis-table-th-color:#ffb648;--cyanosis-table-tht-color:#000;--cyanosis-table-tr-nc-color:#6d5736;--cyanosis-table-trh-color:#947443;--cyanosis-slct-title-color:#000;--cyanosis-slct-titlebg-color:#fe9900;--cyanosis-slct-text-color:#00c888;--cyanosis-slct-bg-color:rgba(175,207,247,0.25);--cyanosis-slct-del-color:#999;--cyanosis-slct-elbg-color:#000;--cyanosis-slct-codebg-color:#ffcb7b;--cyanosis-slct-prebg-color:rgba(160,200,255,0.25)}.markdown-body h1{padding-bottom:4px;font-size:30px}.markdown-body h1,.markdown-body h2{margin-top:36px;margin-bottom:10px;line-height:1.5;color:var(--cyanosis-title-color);transition:color .35s}.markdown-body h2{position:relative;padding-left:10px;padding-right:10px;padding-bottom:10px;font-size:24px;border-bottom:1px solid var(--cyanosis-border-color-2)}.markdown-body h2:before{content:"「";position:absolute;top:-6px;left:-14px}.markdown-body h2:after{content:"」";position:relative;top:6px;right:auto}.markdown-body h3{position:relative;padding-bottom:0;margin-top:30px;margin-bottom:10px;font-size:20px;line-height:1.5;color:var(--cyanosis-title-color);padding-left:6px;transition:color .35s}.markdown-body h3:before{content:"»";padding-right:6px;color:var(--cyanosis-strong-color)}.markdown-body h4{margin-top:24px;font-size:16px}.markdown-body h4,.markdown-body h5{padding-bottom:0;margin-bottom:10px;line-height:1.5;color:var(--cyanosis-title-color);padding-left:6px;transition:color .35s}.markdown-body h5{margin-top:18px;font-size:14px}.markdown-body h6{padding-bottom:0;margin-top:12px;margin-bottom:10px;font-size:12px;line-height:1.5;color:var(--cyanosis-title-color);padding-left:6px;transition:color .35s}.markdown-body p{line-height:inherit;margin-top:16px;margin-bottom:16px}.markdown-body img{max-width:100%}.markdown-body hr{position:relative;width:98%;height:1px;margin-top:32px;margin-bottom:32px;background-image:linear-gradient(90deg,var(--cyanosis-link-color),rgba(255,0,0,.3),hsla(0,0%,100%,.1),rgba(255,0,0,.3),var(--cyanosis-link-color));border-width:0;overflow:visible}.markdown-body hr:after{content:"";position:absolute;margin:auto;left:0;right:0;bottom:0;top:0;display:inline-block;width:60px;height:20px;background-color:var(--cyanosis-bg-color);background-image:url(data:image\u002Fpng;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAYAAABgrToAAAADoklEQVRYR82XTYgcRRTHf2933Q1RjAa9eFO8JHoJ8RQVBQ2iBwXBET0YEUTXNVmNQtTpmeqaWV0XNRq\u002Fo4KoECSCEPSg4CF+BYUkIIiCoCJCPIhC\u002FIhh2Z0nVV27VnZnenumW9i6ddV7\u002F\u002FfrV69fVQurfMgq56NawFTPAU6QyomqXrw6wIZeyhCPebA5buNR+akKyGoAjd6BshthnYdSjqNcRVuOlIUsD2j0SuA94IwuMHdh5ZUykOUBXfSGbmKI54EtAeYIHSZoy5dl4JxvNYBOKdW1KE8BQ8AkVk6WhasWsAiN0TX9gveXQaPP+Aytpc4u+bMI06JNohsYYYYOR2lJWtS3OKDRfcAtQfgDoI6Vo4UCGb0OmAEuDvZvYmVbEd\u002FigC3dzDz7gQu8sPA9kJDK27mBmjqBeLjTg90PDFOjWawFFQd06kZHEfaj3LAIpTRpSXsZ5E06zEYP9sDimnAApYaV2SLZG\u002FwjMeqAkijwW4xQJ5Gf\u002FZzRC8OW3hiBTGGlURRswW55Bh\u002FSsxljrwew8l1PQaM14GngvGDzBUKdDsMeTtgU5o8B92PFlUf3YXUrHa7Fys6lBqcCGnX15YQ2A18FyPd7Crd1A3M8C1wdbH4DD3hWeP6IEXbQkG97ajR1HPFnuPP5jFFq1OWX7hl8WM9l1AO648uNfwLk7tytMeogty+xeQ4rO3r6bdcx1nuwOGsHmaXGtPzae4uzGnLH1kQkvpdZGrHjssBZJrL+pqS05KWc8tgITAPXRzYvYOXe\u002FC2OV43eDcRBDtIhoS2f9wzc0Cv8Wls+zoFzUC5zF0U241h5uZtPfptp6OUM8wbK+cH5GEpCS17P3fJei0Z3+npTxryJ8CPzbKMtn\u002FZyWbkPGl0PuFPkmkjkcb4h4R2ZLwRq1H0ALmvjkf2HwK1Y+T1PY2XABe\u002FsHJ6MxN5lnoSpnC\u002FUGbsTaI5phK2R7x6s3Ffk5YoDOrWm3onwJHBmEP86bPmBrsGaenNoIdnxCH+gPEhLXi0Cl1VBvyPVLSh7gEuC62yAfOIUqabWEaaiucMIk6RyqJ+Q\u002FQM69V26jjW86Gvov\u002FEaoyT8zRCn+Xq7PVrbx0nuYUaO9wM3WAbjCE1NEUw09Um4UV+2OKfYfu5\u002FS19gsAzGKqm6LE5FrShbdS0ku465DjDwKA\u002FoQht19ejqbaEVuRbiLhuHByYLjtUAZpDutzP7cYdHsPJXWbjyNVgFwQoa1WXwf4Jd9YD\u002FAp80+yE7+u9aAAAAAElFTkSuQmCC);background-repeat:no-repeat;background-size:auto 100%;background-position-x:center;transition:background-color .5s}.markdown-body code{padding:.065em .4em;font-size:.87em;color:var(--cyanosis-code-color);word-break:break-word;overflow-x:auto;background-color:var(--cyanosis-code-bg-color);border-radius:2px}.markdown-body code,.markdown-body pre{font-family:Menlo,Monaco,Consolas,Courier New,monospace}.markdown-body pre{overflow:auto;position:relative;line-height:1.75}.markdown-body pre\u003Ecode{display:block;padding:16px 12px;margin:0;font-size:12px;color:#333;word-break:normal;overflow-x:auto;background:var(--cyanosis-code-pre-color)}.markdown-body pre\u003Ecode::-webkit-scrollbar{width:4px;height:4px}.markdown-body pre\u003Ecode::-webkit-scrollbar-track{background-color:var(--cyanosis-border-color)}.markdown-body pre\u003Ecode::-webkit-scrollbar-thumb{background-color:var(--cyanosis-strong-color);border-radius:10px}.markdown-body a{position:relative;text-decoration:none;color:var(--cyanosis-link-color);border-bottom:1px solid var(--cyanosis-border-color)}.markdown-body a:hover{border-bottom-color:var(--cyanosis-linkh-color)}.markdown-body a:active,.markdown-body a:hover{color:var(--cyanosis-linkh-color)}.markdown-body a:after{position:absolute;content:"";top:100%;left:0;width:100%;opacity:0;border-bottom:1px solid var(--cyanosis-border-color);transition:top .3s,opacity .3s;transform:translateZ(0)}.markdown-body a:hover:after{top:0;opacity:1;border-bottom-color:var(--cyanosis-linkh-color)}.markdown-body table{display:inline-block!important;font-size:12px;width:auto;max-width:100%;overflow:auto;border:1px solid var(--cyanosis-table-border-color);border-spacing:0;border-collapse:collapse}.markdown-body table thead{color:#000;text-align:left;font-size:14px;background:#f6f6f6}.markdown-body table tr:nth-child(2n){background-color:var(--cyanosis-table-tr-nc-color)}.markdown-body table tr:hover{background-color:var(--cyanosis-table-trh-color)}.markdown-body table td,.markdown-body table th{padding:12px 8px;line-height:24px;border:1px solid var(--cyanosis-table-border-color)}.markdown-body table th{color:var(--cyanosis-table-tht-color);background-color:var(--cyanosis-table-th-color)}.markdown-body table td{min-width:120px}.markdown-body blockquote{color:var(--cyanosis-blockquote-color);border-left:4px solid var(--cyanosis-strong-color);background-color:var(--cyanosis-blockquote-bg-color);padding:1px 20px;margin:22px 0;transition:color .35s}.markdown-body blockquote:after{display:block;content:""}.markdown-body blockquote\u003Ep{margin:10px 0}.markdown-body b,.markdown-body blockquote\u003Eb,.markdown-body blockquote\u003Estrong,.markdown-body strong{color:var(--cyanosis-strong-color)}.markdown-body em,.markdown-body i{color:var(--cyanosis-em-color)}.markdown-body del{color:var(--cyanosis-del-color)}.markdown-body ol,.markdown-body ul{padding-left:28px}.markdown-body ol li,.markdown-body ul li{margin-bottom:0;list-style:inherit}.markdown-body ol li .task-list-item,.markdown-body ul li .task-list-item{list-style:none}.markdown-body ol li .task-list-item ol,.markdown-body ol li .task-list-item ul,.markdown-body ul li .task-list-item ol,.markdown-body ul li .task-list-item ul{margin-top:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:4px}.markdown-body ol li{padding-left:6px}.markdown-body details\u003Esummary{outline:none;color:var(--cyanosis-title-color);font-size:20px;font-weight:bolder;border-bottom:1px solid var(--cyanosis-border-color);cursor:pointer}.markdown-body details\u003Ep{padding:10px 20px;margin:10px 0 0;color:#666;background-color:var(--cyanosis-blockquote-bg-color);border:2px dashed var(--cyanosis-strong-color)}.markdown-body h1::selection,.markdown-body h2::selection,.markdown-body h3::selection,.markdown-body h4::selection,.markdown-body h5::selection,.markdown-body h6::selection{color:var(--cyanosis-slct-title-color);background-color:var(--cyanosis-slct-titlebg-color)}.markdown-body ol li::selection,.markdown-body p::selection,.markdown-body ul li::selection{color:var(--cyanosis-slct-text-color);background-color:var(--cyanosis-slct-bg-color)}.markdown-body a::selection,.markdown-body b::selection,.markdown-body em::selection,.markdown-body i::selection,.markdown-body strong::selection{background-color:var(--cyanosis-slct-elbg-color)}.markdown-body del::selection{color:var(--cyanosis-slct-del-color);background-color:var(--cyanosis-slct-elbg-color)}.markdown-body table thead th::selection{background-color:transparent}.markdown-body table tbody td::selection{background-color:var(--cyanosis-slct-bg-color)}.markdown-body code::selection{background-color:var(--cyanosis-slct-codebg-color)}.markdown-body pre\u003Ecode::selection{background-color:var(--cyanosis-slct-prebg-color)}.markdown-body .contains-task-list{padding-left:14px;list-style:none}.markdown-body .contains-task-list input[type=checkbox]{position:relative}.markdown-body .contains-task-list input[type=checkbox]:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;width:inherit;height:inherit;background:#f0f8ff;border:1px solid #add6ff;border-radius:2px;box-sizing:border-box;z-index:1}.markdown-body .contains-task-list input[type=checkbox]:checked:after{content:"✓";position:absolute;top:-12px;left:0;right:0;bottom:0;width:0;height:0;color:#f55;font-size:20px;font-weight:700;z-index:2}@media (max-width:720px){.markdown-body h1{font-size:24px}.markdown-body h2{font-size:20px}.markdown-body h3{font-size:18px}}\u003C\u002Fstyle\u003E\u003Cstyle data-highlight data-highlight-key="androidstudio"\u003E.markdown-body pre,.markdown-body pre\u003Ecode.hljs{color:#a9b7c6;background:#282b2e}.hljs-bullet,.hljs-literal,.hljs-number,.hljs-symbol{color:#6897bb}.hljs-deletion,.hljs-keyword,.hljs-selector-tag{color:#cc7832}.hljs-link,.hljs-template-variable,.hljs-variable{color:#629755}.hljs-comment,.hljs-quote{color:grey}.hljs-meta{color:#bbb529}.hljs-addition,.hljs-attribute,.hljs-string{color:#6a8759}.hljs-section,.hljs-title,.hljs-type{color:#ffc66d}.hljs-name,.hljs-selector-class,.hljs-selector-id{color:#e8bf6a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}\u003C\u002Fstyle\u003E\u003Cp\u003E\u003Cstrong\u003E当学习成为了习惯，知识也就变成了常识。\u003C\u002Fstrong\u003E 感谢各位的 \u003Cstrong\u003E点赞\u003C\u002Fstrong\u003E、\u003Cstrong\u003E收藏\u003C\u002Fstrong\u003E和\u003Cstrong\u003E评论\u003C\u002Fstrong\u003E。\u003C\u002Fp\u003E\n\u003Cp\u003E新视频和文章会第一时间在微信公众号发送，欢迎关注：\u003Ca href="https:\u002F\u002Flink.juejin.cn?target=https%3A%2F%2Fgitee.com%2Fliyongning%2Ftypora-image-bed%2Fraw%2Fmaster%2F202202171742614.jpg" target="_blank" title="https:\u002F\u002Fgitee.com\u002Fliyongning\u002Ftypora-image-bed\u002Fraw\u002Fmaster\u002F202202171742614.jpg" ref="nofollow noopener noreferrer"\u003E李永宁lyn\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E文章已收录到 \u003Ca href="https:\u002F\u002Flink.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fliyongning%2Fblog" target="_blank" title="https:\u002F\u002Fgithub.com\u002Fliyongning\u002Fblog" ref="nofollow noopener noreferrer"\u003Egithub\u003C\u002Fa\u003E，欢迎 Watch 和 Star。\u003C\u002Fp\u003E\n\u003Ch1 data-id="heading-0"\u003E目标\u003C\u002Fh1\u003E\n\u003Cp\u003E深入理解 Vue 的初始化过程，再也不怕 \u003Cstrong\u003E面试官\u003C\u002Fstrong\u003E 的那道面试题：\u003Ccode\u003Enew Vue(options)\u003C\u002Fcode\u003E 发生了什么？\u003C\u002Fp\u003E\n\u003Ch1 data-id="heading-1"\u003E找入口\u003C\u002Fh1\u003E\n\u003Cp\u003E想知道 \u003Ccode\u003Enew Vue(options)\u003C\u002Fcode\u003E 都做了什么，就得先找到 Vue 的构造函数是在哪声明的，有两个办法：\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E\n\u003Cp\u003E从 rollup 配置文件中找到编译的入口，然后一步步找到 Vue 构造函数，这种方式 \u003Cstrong\u003E费劲\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E通过编写示例代码，然后打断点的方式，一步到位，\u003Cstrong\u003E简单\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E我们就采用第二种方式，写示例，打断点，一步到位。\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E在 \u003Ccode\u003E\u002Fexamples\u003C\u002Fcode\u003E 目录下增加一个示例文件 —— \u003Ccode\u003Etest.html\u003C\u002Fcode\u003E，在文件中添加如下内容：\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cpre\u003E\u003Ccode class="hljs language-html copyable" lang="html"\u003E\u003Cspan class="hljs-meta"\u003E&#x3C;!DOCTYPE \u003Cspan class="hljs-keyword"\u003Ehtml\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-tag"\u003E&#x3C;\u003Cspan class="hljs-name"\u003Ehtml\u003C\u002Fspan\u003E \u003Cspan class="hljs-attr"\u003Elang\u003C\u002Fspan\u003E=\u003Cspan class="hljs-string"\u003E"en"\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-tag"\u003E&#x3C;\u003Cspan class="hljs-name"\u003Ehead\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-tag"\u003E&#x3C;\u003Cspan class="hljs-name"\u003Emeta\u003C\u002Fspan\u003E \u003Cspan class="hljs-attr"\u003Echarset\u003C\u002Fspan\u003E=\u003Cspan class="hljs-string"\u003E"UTF-8"\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-tag"\u003E&#x3C;\u003Cspan class="hljs-name"\u003Etitle\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003EVue 源码解读\u003Cspan class="hljs-tag"\u003E&#x3C;\u002F\u003Cspan class="hljs-name"\u003Etitle\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-tag"\u003E&#x3C;\u002F\u003Cspan class="hljs-name"\u003Ehead\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-tag"\u003E&#x3C;\u003Cspan class="hljs-name"\u003Ebody\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-tag"\u003E&#x3C;\u003Cspan class="hljs-name"\u003Ediv\u003C\u002Fspan\u003E \u003Cspan class="hljs-attr"\u003Eid\u003C\u002Fspan\u003E=\u003Cspan class="hljs-string"\u003E"app"\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n    {{ msg }}\n  \u003Cspan class="hljs-tag"\u003E&#x3C;\u002F\u003Cspan class="hljs-name"\u003Ediv\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-tag"\u003E&#x3C;\u003Cspan class="hljs-name"\u003Escript\u003C\u002Fspan\u003E \u003Cspan class="hljs-attr"\u003Esrc\u003C\u002Fspan\u003E=\u003Cspan class="hljs-string"\u003E"..\u002Fdist\u002Fvue.js"\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\u003Cspan class="hljs-tag"\u003E&#x3C;\u002F\u003Cspan class="hljs-name"\u003Escript\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-tag"\u003E&#x3C;\u003Cspan class="hljs-name"\u003Escript\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\u003Cspan class="javascript"\u003E\n    \u003Cspan class="hljs-keyword"\u003Edebugger\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-keyword"\u003Enew\u003C\u002Fspan\u003E \u003Cspan class="hljs-title class_"\u003EVue\u003C\u002Fspan\u003E({\n      \u003Cspan class="hljs-attr"\u003Eel\u003C\u002Fspan\u003E: \u003Cspan class="hljs-string"\u003E\'#app\'\u003C\u002Fspan\u003E,\n      \u003Cspan class="hljs-attr"\u003Edata\u003C\u002Fspan\u003E: {\n        \u003Cspan class="hljs-attr"\u003Emsg\u003C\u002Fspan\u003E: \u003Cspan class="hljs-string"\u003E\'hello vue\'\u003C\u002Fspan\u003E\n      }\n    })\n  \u003C\u002Fspan\u003E\u003Cspan class="hljs-tag"\u003E&#x3C;\u002F\u003Cspan class="hljs-name"\u003Escript\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-tag"\u003E&#x3C;\u002F\u003Cspan class="hljs-name"\u003Ebody\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-tag"\u003E&#x3C;\u002F\u003Cspan class="hljs-name"\u003Ehtml\u003C\u002Fspan\u003E\u003E\u003C\u002Fspan\u003E\n\u003Cspan class="copy-code-btn"\u003E复制代码\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Cul\u003E\n\u003Cli\u003E在浏览器中打开控制台，然后打开 \u003Ccode\u003Etest.html\u003C\u002Fcode\u003E，则会进入断点调试，然后找到 Vue 构造函数所在的文件\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Cimg src="https:\u002F\u002Fp1-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002Fd839ea6f3e5d4adcaf1ea9a8f6ff1a70~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp" alt="Mar-26-2021 08-30-52.gif" loading="lazy"\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E得到 Vue 构造函数在 \u003Ccode\u003E\u002Fsrc\u002Fcore\u002Finstance\u002Findex.js\u003C\u002Fcode\u003E 文件中，接下来正式开始源码阅读，带着目标去阅读。\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E在阅读过程中如遇到看不明白的地方，可通过编写示例代码，然后使用浏览器的调试功能进行一步步调试，配合理解，如果还是理解不了，就做个备注继续向后看，也许你看到其它地方，就突然明白这个地方在做什么，或者回头再来看，就会懂了，源码这个东西，一定要多看，要想精通，一遍两遍肯定是不够的\u003C\u002Fp\u003E\n\u003C\u002Fblockquote\u003E\n\u003Ch1 data-id="heading-2"\u003E源码解读 —— Vue 初始化过程\u003C\u002Fh1\u003E\n\u003Ch2 data-id="heading-3"\u003EVue\u003C\u002Fh2\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E\u002Fsrc\u002Fcore\u002Finstance\u002Findex.js\u003C\u002Fp\u003E\n\u003C\u002Fblockquote\u003E\n\u003Cpre\u003E\u003Ccode class="hljs language-javascript copyable" lang="javascript"\u003E\u003Cspan class="hljs-keyword"\u003Eimport\u003C\u002Fspan\u003E { initMixin } \u003Cspan class="hljs-keyword"\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class="hljs-string"\u003E\'.\u002Finit\'\u003C\u002Fspan\u003E\n\n\u003Cspan class="hljs-comment"\u003E\u002F\u002F Vue 构造函数\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-keyword"\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class="hljs-title function_"\u003EVue\u003C\u002Fspan\u003E (options) {\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 调用 Vue.prototype._init 方法，该方法是在 initMixin 中定义的\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-variable language_"\u003Ethis\u003C\u002Fspan\u003E.\u003Cspan class="hljs-title function_"\u003E_init\u003C\u002Fspan\u003E(options)\n}\n\n\u003Cspan class="hljs-comment"\u003E\u002F\u002F 定义 Vue.prototype._init 方法\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-title function_"\u003EinitMixin\u003C\u002Fspan\u003E(\u003Cspan class="hljs-title class_"\u003EVue\u003C\u002Fspan\u003E)\n\n\u003Cspan class="hljs-keyword"\u003Eexport\u003C\u002Fspan\u003E \u003Cspan class="hljs-keyword"\u003Edefault\u003C\u002Fspan\u003E \u003Cspan class="hljs-title class_"\u003EVue\u003C\u002Fspan\u003E\n\u003Cspan class="copy-code-btn"\u003E复制代码\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Ch2 data-id="heading-4"\u003EVue.prototype._init\u003C\u002Fh2\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E\u002Fsrc\u002Fcore\u002Finstance\u002Finit.js\u003C\u002Fp\u003E\n\u003C\u002Fblockquote\u003E\n\u003Cpre\u003E\u003Ccode class="hljs language-javascript copyable" lang="javascript"\u003E\u003Cspan class="hljs-comment"\u003E\u002F**\n * 定义 Vue.prototype._init 方法 \n * \u003Cspan class="hljs-doctag"\u003E@param\u003C\u002Fspan\u003E {\u003Cspan class="hljs-type"\u003E*\u003C\u002Fspan\u003E} Vue Vue 构造函数\n *\u002F\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-keyword"\u003Eexport\u003C\u002Fspan\u003E \u003Cspan class="hljs-keyword"\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class="hljs-title function_"\u003EinitMixin\u003C\u002Fspan\u003E (\u003Cspan class="hljs-title class_"\u003EVue\u003C\u002Fspan\u003E: \u003Cspan class="hljs-title class_"\u003EClass\u003C\u002Fspan\u003E&#x3C;\u003Cspan class="hljs-title class_"\u003EComponent\u003C\u002Fspan\u003E\u003E) {\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 负责 Vue 的初始化过程\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-title class_"\u003EVue\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003E\u003Cspan class="hljs-keyword"\u003Eprototype\u003C\u002Fspan\u003E\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003E_init\u003C\u002Fspan\u003E = \u003Cspan class="hljs-keyword"\u003Efunction\u003C\u002Fspan\u003E (\u003Cspan class="hljs-params"\u003Eoptions?: \u003Cspan class="hljs-built_in"\u003EObject\u003C\u002Fspan\u003E\u003C\u002Fspan\u003E) {\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F vue 实例\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E \u003Cspan class="hljs-attr"\u003Evm\u003C\u002Fspan\u003E: \u003Cspan class="hljs-title class_"\u003EComponent\u003C\u002Fspan\u003E = \u003Cspan class="hljs-variable language_"\u003Ethis\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 每个 vue 实例都有一个 _uid，并且是依次递增的\u003C\u002Fspan\u003E\n    vm.\u003Cspan class="hljs-property"\u003E_uid\u003C\u002Fspan\u003E = uid++\n\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F a flag to avoid this being observed\u003C\u002Fspan\u003E\n    vm.\u003Cspan class="hljs-property"\u003E_isVue\u003C\u002Fspan\u003E = \u003Cspan class="hljs-literal"\u003Etrue\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 处理组件配置项\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (options &#x26;&#x26; options.\u003Cspan class="hljs-property"\u003E_isComponent\u003C\u002Fspan\u003E) {\n      \u003Cspan class="hljs-comment"\u003E\u002F**\n       * 每个子组件初始化时走这里，这里只做了一些性能优化\n       * 将组件配置对象上的一些深层次属性放到 vm.$options 选项中，以提高代码的执行效率\n       *\u002F\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-title function_"\u003EinitInternalComponent\u003C\u002Fspan\u003E(vm, options)\n    } \u003Cspan class="hljs-keyword"\u003Eelse\u003C\u002Fspan\u003E {\n      \u003Cspan class="hljs-comment"\u003E\u002F**\n       * 初始化根组件时走这里，合并 Vue 的全局配置到根组件的局部配置，比如 Vue.component 注册的全局组件会合并到 根实例的 components 选项中\n       * 至于每个子组件的选项合并则发生在两个地方：\n       *   1、Vue.component 方法注册的全局组件在注册时做了选项合并\n       *   2、{ components: { xx } } 方式注册的局部组件在执行编译器生成的 render 函数时做了选项合并，包括根组件中的 components 配置\n       *\u002F\u003C\u002Fspan\u003E\n      vm.\u003Cspan class="hljs-property"\u003E$options\u003C\u002Fspan\u003E = \u003Cspan class="hljs-title function_"\u003EmergeOptions\u003C\u002Fspan\u003E(\n        \u003Cspan class="hljs-title function_"\u003EresolveConstructorOptions\u003C\u002Fspan\u003E(vm.\u003Cspan class="hljs-property"\u003Econstructor\u003C\u002Fspan\u003E),\n        options || {},\n        vm\n      )\n    }\n    \u003Cspan class="hljs-comment"\u003E\u002F* istanbul ignore else *\u002F\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (process.\u003Cspan class="hljs-property"\u003Eenv\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003ENODE_ENV\u003C\u002Fspan\u003E !== \u003Cspan class="hljs-string"\u003E\'production\'\u003C\u002Fspan\u003E) {\n      \u003Cspan class="hljs-comment"\u003E\u002F\u002F 设置代理，将 vm 实例上的属性代理到 vm._renderProxy\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-title function_"\u003EinitProxy\u003C\u002Fspan\u003E(vm)\n    } \u003Cspan class="hljs-keyword"\u003Eelse\u003C\u002Fspan\u003E {\n      vm.\u003Cspan class="hljs-property"\u003E_renderProxy\u003C\u002Fspan\u003E = vm\n    }\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F expose real self\u003C\u002Fspan\u003E\n    vm.\u003Cspan class="hljs-property"\u003E_self\u003C\u002Fspan\u003E = vm\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 初始化组件实例关系属性，比如 $parent、$children、$root、$refs 等\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-title function_"\u003EinitLifecycle\u003C\u002Fspan\u003E(vm)\n    \u003Cspan class="hljs-comment"\u003E\u002F**\n     * 初始化自定义事件，这里需要注意一点，所以我们在 &#x3C;comp \u003Cspan class="hljs-doctag"\u003E@click\u003C\u002Fspan\u003E="handleClick" \u002F\u003E 上注册的事件，监听者不是父组件，\n     * 而是子组件本身，也就是说事件的派发和监听者都是子组件本身，和父组件无关\n     *\u002F\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-title function_"\u003EinitEvents\u003C\u002Fspan\u003E(vm)\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 解析组件的插槽信息，得到 vm.$slot，处理渲染函数，得到 vm.$createElement 方法，即 h 函数\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-title function_"\u003EinitRender\u003C\u002Fspan\u003E(vm)\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 调用 beforeCreate 钩子函数\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-title function_"\u003EcallHook\u003C\u002Fspan\u003E(vm, \u003Cspan class="hljs-string"\u003E\'beforeCreate\'\u003C\u002Fspan\u003E)\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 初始化组件的 inject 配置项，得到 result[key] = val 形式的配置对象，然后对结果数据进行响应式处理，并代理每个 key 到 vm 实例\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-title function_"\u003EinitInjections\u003C\u002Fspan\u003E(vm) \u003Cspan class="hljs-comment"\u003E\u002F\u002F resolve injections before data\u002Fprops\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 数据响应式的重点，处理 props、methods、data、computed、watch\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-title function_"\u003EinitState\u003C\u002Fspan\u003E(vm)\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 解析组件配置项上的 provide 对象，将其挂载到 vm._provided 属性上\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-title function_"\u003EinitProvide\u003C\u002Fspan\u003E(vm) \u003Cspan class="hljs-comment"\u003E\u002F\u002F resolve provide after data\u002Fprops\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 调用 created 钩子函数\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-title function_"\u003EcallHook\u003C\u002Fspan\u003E(vm, \u003Cspan class="hljs-string"\u003E\'created\'\u003C\u002Fspan\u003E)\n\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 如果发现配置项上有 el 选项，则自动调用 $mount 方法，也就是说有了 el 选项，就不需要再手动调用 $mount，反之，没有 el 则必须手动调用 $mount\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (vm.\u003Cspan class="hljs-property"\u003E$options\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003Eel\u003C\u002Fspan\u003E) {\n      \u003Cspan class="hljs-comment"\u003E\u002F\u002F 调用 $mount 方法，进入挂载阶段\u003C\u002Fspan\u003E\n      vm.$mount(vm.\u003Cspan class="hljs-property"\u003E$options\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003Eel\u003C\u002Fspan\u003E)\n    }\n  }\n}\n\n\u003Cspan class="copy-code-btn"\u003E复制代码\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Ch2 data-id="heading-5"\u003EresolveConstructorOptions\u003C\u002Fh2\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E\u002Fsrc\u002Fcore\u002Finstance\u002Finit.js\u003C\u002Fp\u003E\n\u003C\u002Fblockquote\u003E\n\u003Cpre\u003E\u003Ccode class="hljs language-javascript copyable" lang="javascript"\u003E\u003Cspan class="hljs-comment"\u003E\u002F**\n * 从组件构造函数中解析配置对象 options，并合并基类选项\n * \u003Cspan class="hljs-doctag"\u003E@param\u003C\u002Fspan\u003E {\u003Cspan class="hljs-type"\u003E*\u003C\u002Fspan\u003E} Ctor \n * \u003Cspan class="hljs-doctag"\u003E@returns\u003C\u002Fspan\u003E \n *\u002F\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-keyword"\u003Eexport\u003C\u002Fspan\u003E \u003Cspan class="hljs-keyword"\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class="hljs-title function_"\u003EresolveConstructorOptions\u003C\u002Fspan\u003E (\u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E: \u003Cspan class="hljs-title class_"\u003EClass\u003C\u002Fspan\u003E&#x3C;\u003Cspan class="hljs-title class_"\u003EComponent\u003C\u002Fspan\u003E\u003E) {\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 配置项目\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Elet\u003C\u002Fspan\u003E options = \u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003Eoptions\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (\u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003Esuper\u003C\u002Fspan\u003E) {\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 存在基类，递归解析基类构造函数的选项\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E superOptions = \u003Cspan class="hljs-title function_"\u003EresolveConstructorOptions\u003C\u002Fspan\u003E(\u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003Esuper\u003C\u002Fspan\u003E)\n    \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E cachedSuperOptions = \u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003EsuperOptions\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (superOptions !== cachedSuperOptions) {\n      \u003Cspan class="hljs-comment"\u003E\u002F\u002F 说明基类构造函数选项已经发生改变，需要重新设置\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003EsuperOptions\u003C\u002Fspan\u003E = superOptions\n      \u003Cspan class="hljs-comment"\u003E\u002F\u002F 检查 Ctor.options 上是否有任何后期修改\u002F附加的选项（＃4976）\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E modifiedOptions = \u003Cspan class="hljs-title function_"\u003EresolveModifiedOptions\u003C\u002Fspan\u003E(\u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E)\n      \u003Cspan class="hljs-comment"\u003E\u002F\u002F 如果存在被修改或增加的选项，则合并两个选项\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (modifiedOptions) {\n        \u003Cspan class="hljs-title function_"\u003Eextend\u003C\u002Fspan\u003E(\u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003EextendOptions\u003C\u002Fspan\u003E, modifiedOptions)\n      }\n      \u003Cspan class="hljs-comment"\u003E\u002F\u002F 选项合并，将合并结果赋值为 Ctor.options\u003C\u002Fspan\u003E\n      options = \u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003Eoptions\u003C\u002Fspan\u003E = \u003Cspan class="hljs-title function_"\u003EmergeOptions\u003C\u002Fspan\u003E(superOptions, \u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003EextendOptions\u003C\u002Fspan\u003E)\n      \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (options.\u003Cspan class="hljs-property"\u003Ename\u003C\u002Fspan\u003E) {\n        options.\u003Cspan class="hljs-property"\u003Ecomponents\u003C\u002Fspan\u003E[options.\u003Cspan class="hljs-property"\u003Ename\u003C\u002Fspan\u003E] = \u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E\n      }\n    }\n  }\n  \u003Cspan class="hljs-keyword"\u003Ereturn\u003C\u002Fspan\u003E options\n}\n\n\u003Cspan class="copy-code-btn"\u003E复制代码\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Ch2 data-id="heading-6"\u003EresolveModifiedOptions\u003C\u002Fh2\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E\u002Fsrc\u002Fcore\u002Finstance\u002Finit.js\u003C\u002Fp\u003E\n\u003C\u002Fblockquote\u003E\n\u003Cpre\u003E\u003Ccode class="hljs language-javascript copyable" lang="javascript"\u003E\u003Cspan class="hljs-comment"\u003E\u002F**\n * 解析构造函数选项中后续被修改或者增加的选项\n *\u002F\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-keyword"\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class="hljs-title function_"\u003EresolveModifiedOptions\u003C\u002Fspan\u003E (\u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E: \u003Cspan class="hljs-title class_"\u003EClass\u003C\u002Fspan\u003E&#x3C;\u003Cspan class="hljs-title class_"\u003EComponent\u003C\u002Fspan\u003E\u003E): ?\u003Cspan class="hljs-title class_"\u003EObject\u003C\u002Fspan\u003E {\n  \u003Cspan class="hljs-keyword"\u003Elet\u003C\u002Fspan\u003E modified\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 构造函数选项\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E latest = \u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003Eoptions\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 密封的构造函数选项，备份\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E sealed = \u003Cspan class="hljs-title class_"\u003ECtor\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003EsealedOptions\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 对比两个选项，记录不一致的选项\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Efor\u003C\u002Fspan\u003E (\u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E key \u003Cspan class="hljs-keyword"\u003Ein\u003C\u002Fspan\u003E latest) {\n    \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (latest[key] !== sealed[key]) {\n      \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (!modified) modified = {}\n      modified[key] = latest[key]\n    }\n  }\n  \u003Cspan class="hljs-keyword"\u003Ereturn\u003C\u002Fspan\u003E modified\n}\n\n\u003Cspan class="copy-code-btn"\u003E复制代码\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Ch2 data-id="heading-7"\u003EmergeOptions\u003C\u002Fh2\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E\u002Fsrc\u002Fcore\u002Futil\u002Foptions.js\u003C\u002Fp\u003E\n\u003C\u002Fblockquote\u003E\n\u003Cpre\u003E\u003Ccode class="hljs language-javascript copyable" lang="javascript"\u003E\u003Cspan class="hljs-comment"\u003E\u002F**\n * 合并两个选项，出现相同配置项时，子选项会覆盖父选项的配置\n *\u002F\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-keyword"\u003Eexport\u003C\u002Fspan\u003E \u003Cspan class="hljs-keyword"\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class="hljs-title function_"\u003EmergeOptions\u003C\u002Fspan\u003E (\n  \u003Cspan class="hljs-attr"\u003Eparent\u003C\u002Fspan\u003E: \u003Cspan class="hljs-title class_"\u003EObject\u003C\u002Fspan\u003E,\n  \u003Cspan class="hljs-attr"\u003Echild\u003C\u002Fspan\u003E: \u003Cspan class="hljs-title class_"\u003EObject\u003C\u002Fspan\u003E,\n  vm?: \u003Cspan class="hljs-title class_"\u003EComponent\u003C\u002Fspan\u003E\n): \u003Cspan class="hljs-title class_"\u003EObject\u003C\u002Fspan\u003E {\n  \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (process.\u003Cspan class="hljs-property"\u003Eenv\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003ENODE_ENV\u003C\u002Fspan\u003E !== \u003Cspan class="hljs-string"\u003E\'production\'\u003C\u002Fspan\u003E) {\n    \u003Cspan class="hljs-title function_"\u003EcheckComponents\u003C\u002Fspan\u003E(child)\n  }\n\n  \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (\u003Cspan class="hljs-keyword"\u003Etypeof\u003C\u002Fspan\u003E child === \u003Cspan class="hljs-string"\u003E\'function\'\u003C\u002Fspan\u003E) {\n    child = child.\u003Cspan class="hljs-property"\u003Eoptions\u003C\u002Fspan\u003E\n  }\n\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 标准化 props、inject、directive 选项，方便后续程序的处理\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-title function_"\u003EnormalizeProps\u003C\u002Fspan\u003E(child, vm)\n  \u003Cspan class="hljs-title function_"\u003EnormalizeInject\u003C\u002Fspan\u003E(child, vm)\n  \u003Cspan class="hljs-title function_"\u003EnormalizeDirectives\u003C\u002Fspan\u003E(child)\n\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 处理原始 child 对象上的 extends 和 mixins，分别执行 mergeOptions，将这些继承而来的选项合并到 parent\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F mergeOptions 处理过的对象会含有 _base 属性\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (!child.\u003Cspan class="hljs-property"\u003E_base\u003C\u002Fspan\u003E) {\n    \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (child.\u003Cspan class="hljs-property"\u003Eextends\u003C\u002Fspan\u003E) {\n      parent = \u003Cspan class="hljs-title function_"\u003EmergeOptions\u003C\u002Fspan\u003E(parent, child.\u003Cspan class="hljs-property"\u003Eextends\u003C\u002Fspan\u003E, vm)\n    }\n    \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (child.\u003Cspan class="hljs-property"\u003Emixins\u003C\u002Fspan\u003E) {\n      \u003Cspan class="hljs-keyword"\u003Efor\u003C\u002Fspan\u003E (\u003Cspan class="hljs-keyword"\u003Elet\u003C\u002Fspan\u003E i = \u003Cspan class="hljs-number"\u003E0\u003C\u002Fspan\u003E, l = child.\u003Cspan class="hljs-property"\u003Emixins\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003Elength\u003C\u002Fspan\u003E; i &#x3C; l; i++) {\n        parent = \u003Cspan class="hljs-title function_"\u003EmergeOptions\u003C\u002Fspan\u003E(parent, child.\u003Cspan class="hljs-property"\u003Emixins\u003C\u002Fspan\u003E[i], vm)\n      }\n    }\n  }\n\n  \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E options = {}\n  \u003Cspan class="hljs-keyword"\u003Elet\u003C\u002Fspan\u003E key\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 遍历 父选项\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Efor\u003C\u002Fspan\u003E (key \u003Cspan class="hljs-keyword"\u003Ein\u003C\u002Fspan\u003E parent) {\n    \u003Cspan class="hljs-title function_"\u003EmergeField\u003C\u002Fspan\u003E(key)\n  }\n\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 遍历 子选项，如果父选项不存在该配置，则合并，否则跳过，因为父子拥有同一个属性的情况在上面处理父选项时已经处理过了，用的子选项的值\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Efor\u003C\u002Fspan\u003E (key \u003Cspan class="hljs-keyword"\u003Ein\u003C\u002Fspan\u003E child) {\n    \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (!\u003Cspan class="hljs-title function_"\u003EhasOwn\u003C\u002Fspan\u003E(parent, key)) {\n      \u003Cspan class="hljs-title function_"\u003EmergeField\u003C\u002Fspan\u003E(key)\n    }\n  }\n\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 合并选项，childVal 优先级高于 parentVal\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class="hljs-title function_"\u003EmergeField\u003C\u002Fspan\u003E (key) {\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F strats = Object.create(null)\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E strat = strats[key] || defaultStrat\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 值为如果 childVal 存在则优先使用 childVal，否则使用 parentVal\u003C\u002Fspan\u003E\n    options[key] = \u003Cspan class="hljs-title function_"\u003Estrat\u003C\u002Fspan\u003E(parent[key], child[key], vm, key)\n  }\n  \u003Cspan class="hljs-keyword"\u003Ereturn\u003C\u002Fspan\u003E options\n}\n\n\u003Cspan class="copy-code-btn"\u003E复制代码\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Ch2 data-id="heading-8"\u003EinitInjections\u003C\u002Fh2\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E\u002Fsrc\u002Fcore\u002Finstance\u002Finject.js\u003C\u002Fp\u003E\n\u003C\u002Fblockquote\u003E\n\u003Cpre\u003E\u003Ccode class="hljs language-javascript copyable" lang="javascript"\u003E\u003Cspan class="hljs-comment"\u003E\u002F**\n * 初始化 inject 配置项\n *   1、得到 result[key] = val\n *   2、对结果数据进行响应式处理，代理每个 key 到 vm 实例\n *\u002F\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-keyword"\u003Eexport\u003C\u002Fspan\u003E \u003Cspan class="hljs-keyword"\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class="hljs-title function_"\u003EinitInjections\u003C\u002Fspan\u003E (\u003Cspan class="hljs-attr"\u003Evm\u003C\u002Fspan\u003E: \u003Cspan class="hljs-title class_"\u003EComponent\u003C\u002Fspan\u003E) {\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 解析 inject 配置项，然后从祖代组件的配置中找到 配置项中每一个 key 对应的 val，最后得到 result[key] = val 的结果\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E result = \u003Cspan class="hljs-title function_"\u003EresolveInject\u003C\u002Fspan\u003E(vm.\u003Cspan class="hljs-property"\u003E$options\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003Einject\u003C\u002Fspan\u003E, vm)\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 对 result 做 数据响应式处理，也有代理 inject 配置中每个 key 到 vm 实例的作用。\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-comment"\u003E\u002F\u002F 不不建议在子组件去更改这些数据，因为一旦祖代组件中 注入的 provide 发生更改，你在组件中做的更改就会被覆盖\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (result) {\n    \u003Cspan class="hljs-title function_"\u003EtoggleObserving\u003C\u002Fspan\u003E(\u003Cspan class="hljs-literal"\u003Efalse\u003C\u002Fspan\u003E)\n    \u003Cspan class="hljs-title class_"\u003EObject\u003C\u002Fspan\u003E.\u003Cspan class="hljs-title function_"\u003Ekeys\u003C\u002Fspan\u003E(result).\u003Cspan class="hljs-title function_"\u003EforEach\u003C\u002Fspan\u003E(\u003Cspan class="hljs-function"\u003E\u003Cspan class="hljs-params"\u003Ekey\u003C\u002Fspan\u003E =\u003E\u003C\u002Fspan\u003E {\n      \u003Cspan class="hljs-comment"\u003E\u002F* istanbul ignore else *\u002F\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (process.\u003Cspan class="hljs-property"\u003Eenv\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003ENODE_ENV\u003C\u002Fspan\u003E !== \u003Cspan class="hljs-string"\u003E\'production\'\u003C\u002Fspan\u003E) {\n        \u003Cspan class="hljs-title function_"\u003EdefineReactive\u003C\u002Fspan\u003E(vm, key, result[key], \u003Cspan class="hljs-function"\u003E() =\u003E\u003C\u002Fspan\u003E {\n          \u003Cspan class="hljs-title function_"\u003Ewarn\u003C\u002Fspan\u003E(\n            \u003Cspan class="hljs-string"\u003E`Avoid mutating an injected value directly since the changes will be `\u003C\u002Fspan\u003E +\n            \u003Cspan class="hljs-string"\u003E`overwritten whenever the provided component re-renders. `\u003C\u002Fspan\u003E +\n            \u003Cspan class="hljs-string"\u003E`injection being mutated: "\u003Cspan class="hljs-subst"\u003E${key}\u003C\u002Fspan\u003E"`\u003C\u002Fspan\u003E,\n            vm\n          )\n        })\n      } \u003Cspan class="hljs-keyword"\u003Eelse\u003C\u002Fspan\u003E {\n        \u003Cspan class="hljs-title function_"\u003EdefineReactive\u003C\u002Fspan\u003E(vm, key, result[key])\n      }\n    })\n    \u003Cspan class="hljs-title function_"\u003EtoggleObserving\u003C\u002Fspan\u003E(\u003Cspan class="hljs-literal"\u003Etrue\u003C\u002Fspan\u003E)\n  }\n}\n\n\u003Cspan class="copy-code-btn"\u003E复制代码\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Ch2 data-id="heading-9"\u003EresolveInject\u003C\u002Fh2\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E\u002Fsrc\u002Fcore\u002Finstance\u002Finject.js\u003C\u002Fp\u003E\n\u003C\u002Fblockquote\u003E\n\u003Cpre\u003E\u003Ccode class="hljs language-javascript copyable" lang="javascript"\u003E\u003Cspan class="hljs-comment"\u003E\u002F**\n * 解析 inject 配置项，从祖代组件的 provide 配置中找到 key 对应的值，否则用 默认值，最后得到 result[key] = val\n * inject 对象肯定是以下这个结构，因为在 合并 选项时对组件配置对象做了标准化处理\n * \u003Cspan class="hljs-doctag"\u003E@param\u003C\u002Fspan\u003E {\u003Cspan class="hljs-type"\u003E*\u003C\u002Fspan\u003E} inject = {\n *  key: {\n *    from: provideKey,\n *    default: xx\n *  }\n * }\n *\u002F\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-keyword"\u003Eexport\u003C\u002Fspan\u003E \u003Cspan class="hljs-keyword"\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class="hljs-title function_"\u003EresolveInject\u003C\u002Fspan\u003E (\u003Cspan class="hljs-attr"\u003Einject\u003C\u002Fspan\u003E: any, \u003Cspan class="hljs-attr"\u003Evm\u003C\u002Fspan\u003E: \u003Cspan class="hljs-title class_"\u003EComponent\u003C\u002Fspan\u003E): ?\u003Cspan class="hljs-title class_"\u003EObject\u003C\u002Fspan\u003E {\n  \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (inject) {\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F inject is :any because flow is not smart enough to figure out cached\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E result = \u003Cspan class="hljs-title class_"\u003EObject\u003C\u002Fspan\u003E.\u003Cspan class="hljs-title function_"\u003Ecreate\u003C\u002Fspan\u003E(\u003Cspan class="hljs-literal"\u003Enull\u003C\u002Fspan\u003E)\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F inject 配置项的所有的 key\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E keys = hasSymbol\n      ? \u003Cspan class="hljs-title class_"\u003EReflect\u003C\u002Fspan\u003E.\u003Cspan class="hljs-title function_"\u003EownKeys\u003C\u002Fspan\u003E(inject)\n      : \u003Cspan class="hljs-title class_"\u003EObject\u003C\u002Fspan\u003E.\u003Cspan class="hljs-title function_"\u003Ekeys\u003C\u002Fspan\u003E(inject)\n\n    \u003Cspan class="hljs-comment"\u003E\u002F\u002F 遍历 key\u003C\u002Fspan\u003E\n    \u003Cspan class="hljs-keyword"\u003Efor\u003C\u002Fspan\u003E (\u003Cspan class="hljs-keyword"\u003Elet\u003C\u002Fspan\u003E i = \u003Cspan class="hljs-number"\u003E0\u003C\u002Fspan\u003E; i &#x3C; keys.\u003Cspan class="hljs-property"\u003Elength\u003C\u002Fspan\u003E; i++) {\n      \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E key = keys[i]\n      \u003Cspan class="hljs-comment"\u003E\u002F\u002F 跳过 __ob__ 对象\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-comment"\u003E\u002F\u002F #6574 in case the inject object is observed...\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (key === \u003Cspan class="hljs-string"\u003E\'__ob__\'\u003C\u002Fspan\u003E) \u003Cspan class="hljs-keyword"\u003Econtinue\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-comment"\u003E\u002F\u002F 拿到 provide 中对应的 key\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E provideKey = inject[key].\u003Cspan class="hljs-property"\u003Efrom\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-keyword"\u003Elet\u003C\u002Fspan\u003E source = vm\n      \u003Cspan class="hljs-comment"\u003E\u002F\u002F 遍历所有的祖代组件，直到 根组件，找到 provide 中对应 key 的值，最后得到 result[key] = provide[provideKey]\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-keyword"\u003Ewhile\u003C\u002Fspan\u003E (source) {\n        \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (source.\u003Cspan class="hljs-property"\u003E_provided\u003C\u002Fspan\u003E &#x26;&#x26; \u003Cspan class="hljs-title function_"\u003EhasOwn\u003C\u002Fspan\u003E(source.\u003Cspan class="hljs-property"\u003E_provided\u003C\u002Fspan\u003E, provideKey)) {\n          result[key] = source.\u003Cspan class="hljs-property"\u003E_provided\u003C\u002Fspan\u003E[provideKey]\n          \u003Cspan class="hljs-keyword"\u003Ebreak\u003C\u002Fspan\u003E\n        }\n        source = source.\u003Cspan class="hljs-property"\u003E$parent\u003C\u002Fspan\u003E\n      }\n      \u003Cspan class="hljs-comment"\u003E\u002F\u002F 如果上一个循环未找到，则采用 inject[key].default，如果没有设置 default 值，则抛出错误\u003C\u002Fspan\u003E\n      \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (!source) {\n        \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (\u003Cspan class="hljs-string"\u003E\'default\'\u003C\u002Fspan\u003E \u003Cspan class="hljs-keyword"\u003Ein\u003C\u002Fspan\u003E inject[key]) {\n          \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E provideDefault = inject[key].\u003Cspan class="hljs-property"\u003Edefault\u003C\u002Fspan\u003E\n          result[key] = \u003Cspan class="hljs-keyword"\u003Etypeof\u003C\u002Fspan\u003E provideDefault === \u003Cspan class="hljs-string"\u003E\'function\'\u003C\u002Fspan\u003E\n            ? provideDefault.\u003Cspan class="hljs-title function_"\u003Ecall\u003C\u002Fspan\u003E(vm)\n            : provideDefault\n        } \u003Cspan class="hljs-keyword"\u003Eelse\u003C\u002Fspan\u003E \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (process.\u003Cspan class="hljs-property"\u003Eenv\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003ENODE_ENV\u003C\u002Fspan\u003E !== \u003Cspan class="hljs-string"\u003E\'production\'\u003C\u002Fspan\u003E) {\n          \u003Cspan class="hljs-title function_"\u003Ewarn\u003C\u002Fspan\u003E(\u003Cspan class="hljs-string"\u003E`Injection "\u003Cspan class="hljs-subst"\u003E${key}\u003C\u002Fspan\u003E" not found`\u003C\u002Fspan\u003E, vm)\n        }\n      }\n    }\n    \u003Cspan class="hljs-keyword"\u003Ereturn\u003C\u002Fspan\u003E result\n  }\n}\n\n\u003Cspan class="copy-code-btn"\u003E复制代码\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Ch2 data-id="heading-10"\u003EinitProvide\u003C\u002Fh2\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E\u002Fsrc\u002Fcore\u002Finstance\u002Finject.js\u003C\u002Fp\u003E\n\u003C\u002Fblockquote\u003E\n\u003Cpre\u003E\u003Ccode class="hljs language-javascript copyable" lang="javascript"\u003E\u003Cspan class="hljs-comment"\u003E\u002F**\n * 解析组件配置项上的 provide 对象，将其挂载到 vm._provided 属性上 \n *\u002F\u003C\u002Fspan\u003E\n\u003Cspan class="hljs-keyword"\u003Eexport\u003C\u002Fspan\u003E \u003Cspan class="hljs-keyword"\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class="hljs-title function_"\u003EinitProvide\u003C\u002Fspan\u003E (\u003Cspan class="hljs-attr"\u003Evm\u003C\u002Fspan\u003E: \u003Cspan class="hljs-title class_"\u003EComponent\u003C\u002Fspan\u003E) {\n  \u003Cspan class="hljs-keyword"\u003Econst\u003C\u002Fspan\u003E provide = vm.\u003Cspan class="hljs-property"\u003E$options\u003C\u002Fspan\u003E.\u003Cspan class="hljs-property"\u003Eprovide\u003C\u002Fspan\u003E\n  \u003Cspan class="hljs-keyword"\u003Eif\u003C\u002Fspan\u003E (provide) {\n    vm.\u003Cspan class="hljs-property"\u003E_provided\u003C\u002Fspan\u003E = \u003Cspan class="hljs-keyword"\u003Etypeof\u003C\u002Fspan\u003E provide === \u003Cspan class="hljs-string"\u003E\'function\'\u003C\u002Fspan\u003E\n      ? provide.\u003Cspan class="hljs-title function_"\u003Ecall\u003C\u002Fspan\u003E(vm)\n      : provide\n  }\n}\n\n\u003Cspan class="copy-code-btn"\u003E复制代码\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\n\u003Ch1 data-id="heading-11"\u003E总结\u003C\u002Fh1\u003E\n\u003Cp\u003EVue 的初始化过程（new Vue(options)）都做了什么？\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E\n\u003Cp\u003E处理组件配置项\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E\n\u003Cp\u003E初始化根组件时进行了选项合并操作，将全局配置合并到根组件的局部配置上\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E初始化每个子组件时做了一些性能优化，将组件配置对象上的一些深层次属性放到 vm.$options 选项中，以提高代码的执行效率\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E初始化组件实例的关系属性，比如 $parent、$children、$root、$refs 等\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E处理自定义事件\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E调用 beforeCreate 钩子函数\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E初始化组件的 inject 配置项，得到 \u003Ccode\u003Eret[key] = val\u003C\u002Fcode\u003E 形式的配置对象，然后对该配置对象进行浅层的响应式处理（只处理了对象第一层数据），并代理每个 key 到 vm 实例上\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E数据响应式，处理 props、methods、data、computed、watch 等选项\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E解析组件配置项上的 provide 对象，将其挂载到 vm._provided 属性上\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E调用 created 钩子函数\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E如果发现配置项上有 el 选项，则自动调用 $mount 方法，也就是说有了 el 选项，就不需要再手动调用 $mount 方法，反之，没提供 el 选项则必须调用 $mount\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E接下来则进入挂载阶段\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch1 data-id="heading-12"\u003E链接\u003C\u002Fh1\u003E\n\u003Cul\u003E\n\u003Cli\u003E\n\u003Cp\u003E\u003Ca href="https:\u002F\u002Flink.juejin.cn?target=https%3A%2F%2Fgitee.com%2Fliyongning%2Ftypora-image-bed%2Fraw%2Fmaster%2F202202171742614.jpg" target="_blank" title="https:\u002F\u002Fgitee.com\u002Fliyongning\u002Ftypora-image-bed\u002Fraw\u002Fmaster\u002F202202171742614.jpg" ref="nofollow noopener noreferrer"\u003E配套视频，关注微信公众号回复\u003C\u002Fa\u003E："精通 Vue 技术栈源码原理视频版" 获取\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E\u003Ca href="https:\u002F\u002Flink.juejin.cn?target=https%3A%2F%2Fmp.weixin.qq.com%2Fmp%2Fappmsgalbum%3F__biz%3DMzA3NTk4NjQ1OQ%3D%3D%26action%3Dgetalbum%26album_id%3D2273541436891693065%23wechat_redirect" target="_blank" title="https:\u002F\u002Fmp.weixin.qq.com\u002Fmp\u002Fappmsgalbum?__biz=MzA3NTk4NjQ1OQ==&#x26;action=getalbum&#x26;album_id=2273541436891693065#wechat_redirect" ref="nofollow noopener noreferrer"\u003E精通 Vue 技术栈源码原理 专栏\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003E\n\u003Cp\u003E\u003Ca href="https:\u002F\u002Flink.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fliyongning%2FVue" target="_blank" title="https:\u002F\u002Fgithub.com\u002Fliyongning\u002FVue" ref="nofollow noopener noreferrer"\u003Egithub 仓库 liyongning\u002FVue\u003C\u002Fa\u003E 欢迎 Star\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E感谢各位的：\u003Cstrong\u003E点赞\u003C\u002Fstrong\u003E、\u003Cstrong\u003E收藏\u003C\u002Fstrong\u003E和\u003Cstrong\u003E评论\u003C\u002Fstrong\u003E，我们下期见。\u003C\u002Fp\u003E\n\u003Chr\u003E\n\u003Cp\u003E\u003Cstrong\u003E当学习成为了习惯，知识也就变成了常识。\u003C\u002Fstrong\u003E 感谢各位的 \u003Cstrong\u003E点赞\u003C\u002Fstrong\u003E、\u003Cstrong\u003E收藏\u003C\u002Fstrong\u003E和\u003Cstrong\u003E评论\u003C\u002Fstrong\u003E。\u003C\u002Fp\u003E\n\u003Cp\u003E新视频和文章会第一时间在微信公众号发送，欢迎关注：\u003Ca href="https:\u002F\u002Flink.juejin.cn?target=https%3A%2F%2Fgitee.com%2Fliyongning%2Ftypora-image-bed%2Fraw%2Fmaster%2F202202171742614.jpg" target="_blank" title="https:\u002F\u002Fgitee.com\u002Fliyongning\u002Ftypora-image-bed\u002Fraw\u002Fmaster\u002F202202171742614.jpg" ref="nofollow noopener noreferrer"\u003E李永宁lyn\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E文章已收录到 \u003Ca href="https:\u002F\u002Flink.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fliyongning%2Fblog" target="_blank" title="https:\u002F\u002Fgithub.com\u002Fliyongning\u002Fblog" ref="nofollow noopener noreferrer"\u003Egithub 仓库 liyongning\u002Fblog\u003C\u002Fa\u003E，欢迎 Watch 和 Star。\u003C\u002Fp\u003E',
                hitArticleCache: d,
                relatedLoaded: a,
                dynamicDataReady: a,
                actionType: {
                  FETCH: "view\u002Fcolumn\u002FFETCH",
                  FETCH_ADDITIONAL: "view\u002Fcolumn\u002FFETCH_ADDITIONAL",
                  FETCH_SIDEBAR_ADENTRY:
                    "view\u002Fcolumn\u002FFETCH_SIDEBAR_ADENTRY",
                  FETCH_AUTHOR_EXTRA:
                    "view\u002Fcolumn\u002FFETCH_AUTHOR_EXTRA",
                  RESET: "view\u002Fcolumn\u002FRESET",
                },
                recommendedArticleList: {
                  list: [],
                  cursor: f,
                  loading: a,
                  skeleton: a,
                  hasMore: a,
                  articleId: e,
                  actionType: {
                    UPDATE_STATE:
                      "view\u002Fcolumn\u002Frecommend-List\u002FUPDATE_STATE",
                    FETCH_MORE:
                      "view\u002Fcolumn\u002Frecommend-List\u002FFETCH_MORE",
                    FETCH: "view\u002Fcolumn\u002Frecommend-List\u002FFETCH",
                    RESET: "view\u002Fcolumn\u002Frecommend-List\u002FRESET",
                  },
                },
              },
              collection: {
                collection: { author: {} },
                actionType: {
                  FETCH: "@\u002Fview\u002Fcollection\u002FFETCH",
                  REFRESH: "@\u002Fview\u002Fcollection\u002FREFRESH",
                  RESET: "@\u002Fview\u002Fcollection\u002FRESET",
                },
                list: {
                  pageSize: h,
                  page: g,
                  total: b,
                  pointer: c,
                  lastPointer: c,
                  list: [],
                  loading: a,
                  error: c,
                  canPrev: d,
                  canNext: d,
                  linkList: [],
                  lastFetchOnServer: a,
                  actionType: {
                    UPDATE: "@\u002Fview\u002Fcollection\u002Flist\u002FUPDATE",
                    FETCH: "@\u002Fview\u002Fcollection\u002Flist\u002FFETCH",
                    FORCE_FETCH:
                      "@\u002Fview\u002Fcollection\u002Flist\u002FFORCE_FETCH",
                    FETCH_MORE:
                      "@\u002Fview\u002Fcollection\u002Flist\u002FFETCH_MORE",
                    RESET: "@\u002Fview\u002Fcollection\u002Flist\u002FRESET",
                  },
                  id: e,
                  sort: o,
                },
              },
              gettingStarted: {
                category: {},
                actionType: {
                  UPDATE_STATE:
                    "@\u002Fview\u002FgettingStarted\u002FUPDATE_STATE",
                  FOLLOW: "@\u002Fview\u002FgettingStarted\u002FFOLLOW",
                  RESET: "@\u002Fview\u002FgettingStarted\u002FRESET",
                  UPDATE_CATEGORY:
                    "@\u002Fview\u002FgettingStarted\u002FUPDATE_CATEGORY",
                },
              },
              pin: {
                pin: { user: {}, imageUrlList: [] },
                pinList: [],
                actionType: {
                  FETCH: "@\u002Fview\u002Fpin\u002FFETCH",
                  RESET: "@\u002Fview\u002Fpin\u002FRESET",
                },
                sidebar: {
                  list: [],
                  after: e,
                  loading: a,
                  isRecommend: a,
                  hasNextPage: d,
                  actionType: {
                    UPDATE_STATE:
                      "@\u002Fview\u002Fpin\u002Fsidebar\u002FUPDATE_STATE",
                    FETCH_MORE:
                      "@\u002Fview\u002Fpin\u002Fsidebar\u002FFETCH_MORE",
                    FETCH: "@\u002Fview\u002Fpin\u002Fsidebar\u002FFETCH",
                    RESET: "@\u002Fview\u002Fpin\u002Fsidebar\u002FRESET",
                  },
                },
                commentList: {
                  pageSize: h,
                  page: g,
                  total: b,
                  pointer: c,
                  lastPointer: c,
                  list: [],
                  loading: a,
                  error: c,
                  canPrev: d,
                  canNext: d,
                  linkList: [],
                  lastFetchOnServer: a,
                  actionType: {
                    UPDATE: "@\u002Fview\u002Fpin\u002FcommentList\u002FUPDATE",
                    FETCH: "@\u002Fview\u002Fpin\u002FcommentList\u002FFETCH",
                    FORCE_FETCH:
                      "@\u002Fview\u002Fpin\u002FcommentList\u002FFORCE_FETCH",
                    FETCH_MORE:
                      "@\u002Fview\u002Fpin\u002FcommentList\u002FFETCH_MORE",
                    RESET: "@\u002Fview\u002Fpin\u002FcommentList\u002FRESET",
                  },
                  pinId: c,
                },
                subCommentList: {
                  pageSize: h,
                  page: g,
                  total: b,
                  pointer: c,
                  lastPointer: c,
                  list: [],
                  loading: a,
                  error: c,
                  canPrev: d,
                  canNext: d,
                  linkList: [],
                  lastFetchOnServer: a,
                  actionType: {
                    UPDATE:
                      "@\u002Fview\u002Fpin\u002FsubCommentList\u002FUPDATE",
                    FETCH:
                      "@\u002Fview\u002Fpin\u002FsubCommentList\u002FFETCH",
                    FORCE_FETCH:
                      "@\u002Fview\u002Fpin\u002FsubCommentList\u002FFORCE_FETCH",
                    FETCH_MORE:
                      "@\u002Fview\u002Fpin\u002FsubCommentList\u002FFETCH_MORE",
                    RESET:
                      "@\u002Fview\u002Fpin\u002FsubCommentList\u002FRESET",
                  },
                  commentId: c,
                },
              },
              topic: {
                topic: e,
                followedTopicList: [],
                actionType: {
                  FETCH: "@\u002Fview\u002Ftopic\u002FFETCH",
                  UPDATE_STATE: "@\u002Fview\u002Ftopic\u002FUPDATE_STATE",
                  RESET: "@\u002Fview\u002Ftopic\u002FRESET",
                },
                allTopicList: {
                  pageSize: K,
                  page: b,
                  total: b,
                  pointer: c,
                  lastPointer: c,
                  list: [],
                  loading: a,
                  error: c,
                  canPrev: d,
                  canNext: d,
                  linkList: [],
                  lastFetchOnServer: a,
                  actionType: {
                    UPDATE:
                      "@\u002Fview\u002Ftopic\u002FallTopicList\u002FUPDATE",
                    FETCH:
                      "@\u002Fview\u002Ftopic\u002FallTopicList\u002FFETCH",
                    FORCE_FETCH:
                      "@\u002Fview\u002Ftopic\u002FallTopicList\u002FFORCE_FETCH",
                    FETCH_MORE:
                      "@\u002Fview\u002Ftopic\u002FallTopicList\u002FFETCH_MORE",
                    RESET:
                      "@\u002Fview\u002Ftopic\u002FallTopicList\u002FRESET",
                  },
                  sortType: n,
                },
                pinlist: {
                  pageSize: h,
                  page: g,
                  total: b,
                  pointer: c,
                  lastPointer: c,
                  list: [],
                  loading: a,
                  error: c,
                  canPrev: d,
                  canNext: d,
                  linkList: [],
                  lastFetchOnServer: a,
                  actionType: {
                    UPDATE: "@\u002Fview\u002Ftopic\u002FpinList\u002FUPDATE",
                    FETCH: "@\u002Fview\u002Ftopic\u002FpinList\u002FFETCH",
                    FORCE_FETCH:
                      "@\u002Fview\u002Ftopic\u002FpinList\u002FFORCE_FETCH",
                    FETCH_MORE:
                      "@\u002Fview\u002Ftopic\u002FpinList\u002FFETCH_MORE",
                    RESET: "@\u002Fview\u002Ftopic\u002FpinList\u002FRESET",
                  },
                  sortType: r,
                },
                sidebar: {
                  actionType: {
                    RESET: "@\u002Fview\u002Ftopic\u002Fsidebar\u002FRESET",
                    UPDATE_STATE:
                      "@\u002Fview\u002Ftopic\u002Fsidebar\u002FUPDATE_STATE",
                  },
                  attender: {
                    pageSize: h,
                    page: g,
                    total: b,
                    pointer: c,
                    lastPointer: c,
                    list: [],
                    loading: a,
                    error: c,
                    canPrev: d,
                    canNext: d,
                    linkList: [],
                    lastFetchOnServer: a,
                    actionType: {
                      UPDATE:
                        "@\u002Fview\u002Ftopic\u002Fsidebar\u002Fattender\u002FUPDATE",
                      FETCH:
                        "@\u002Fview\u002Ftopic\u002Fsidebar\u002Fattender\u002FFETCH",
                      FORCE_FETCH:
                        "@\u002Fview\u002Ftopic\u002Fsidebar\u002Fattender\u002FFORCE_FETCH",
                      FETCH_MORE:
                        "@\u002Fview\u002Ftopic\u002Fsidebar\u002Fattender\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Ftopic\u002Fsidebar\u002Fattender\u002FRESET",
                    },
                    topicId: c,
                  },
                },
                followedList: {
                  pageSize: K,
                  page: b,
                  total: b,
                  pointer: c,
                  lastPointer: c,
                  list: [],
                  loading: a,
                  error: c,
                  canPrev: d,
                  canNext: d,
                  linkList: [],
                  lastFetchOnServer: a,
                  actionType: {
                    UPDATE:
                      "@\u002Fview\u002Ftopic\u002FfollowedList\u002FUPDATE",
                    FETCH:
                      "@\u002Fview\u002Ftopic\u002FfollowedList\u002FFETCH",
                    FORCE_FETCH:
                      "@\u002Fview\u002Ftopic\u002FfollowedList\u002FFORCE_FETCH",
                    FETCH_MORE:
                      "@\u002Fview\u002Ftopic\u002FfollowedList\u002FFETCH_MORE",
                    RESET:
                      "@\u002Fview\u002Ftopic\u002FfollowedList\u002FRESET",
                  },
                  after: b,
                },
              },
              recommendationIndex: {
                actionType: {
                  FETCH_USER: "@\u002Fview\u002Frecommendation\u002FFETCH_USER",
                  FETCH_MORE: "@\u002Fview\u002Frecommendation\u002FFETCH_MORE",
                  RESET: "@\u002Fview\u002Frecommendation\u002FRESET",
                  FETCH: "@\u002Fview\u002Frecommendation\u002FFETCH",
                },
                cursor: e,
                hasMore: e,
                userList: [],
                loading: a,
                skeleton: d,
                category: l,
                categoryNavList: [],
                serverRenderUserList: a,
              },
              event: {
                event: {},
                loading: a,
                user: {},
                actionType: {
                  FETCH: "view\u002Fevent\u002FFETCH",
                  RESET: "view\u002Fevent\u002FRESET",
                },
              },
              academyIndex: {
                academy: {},
                bannerList: [],
                qualitiedList: [],
                latestList: [],
                offlineList: [],
                loading: a,
                user: {},
                actionType: {
                  FETCH: "view\u002Facademy\u002FFETCH",
                  RESET: "view\u002Facademy\u002FRESET",
                },
              },
              coursesIndex: {
                loading: a,
                list: [],
                sort: "online",
                actionType: {
                  FETCH: "view\u002Fcourses\u002FFETCH",
                  RESET: "view\u002Fcourses\u002FRESET",
                  FETCH_MORE: "view\u002Fcourses\u002FFETCH_MORE",
                },
              },
              team: {
                team: {},
                loading: d,
                actionType: {
                  FETCH: "@\u002Fview\u002Fteam\u002FFETCH",
                  RESET: "@\u002Fview\u002Fteam\u002FRESET",
                  UPDATE: "@\u002Fview\u002Fteam\u002FUPDATE",
                  FOLLOW: "@\u002Fview\u002Fteam\u002FFOLLOW",
                },
                detailList: {
                  actionType: {
                    RESET: "@\u002Fview\u002Fteam\u002FdetailList\u002FRESET",
                  },
                  posts: {
                    list: [],
                    hasMore: a,
                    skeleton: a,
                    loading: a,
                    sort: o,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fposts\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fposts\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fposts\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fposts\u002FRESET",
                    },
                  },
                  pins: {
                    list: [],
                    hasMore: a,
                    loading: a,
                    skeleton: d,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fpins\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fpins\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fpins\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fpins\u002FRESET",
                    },
                  },
                  hire: {
                    list: [],
                    hasMore: a,
                    cursor: f,
                    loading: a,
                    skeleton: d,
                    actionType: {
                      FETCH:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fhire\u002FFETCH",
                      UPDATE_STATE:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fhire\u002FUPDATE_STATE",
                      FETCH_MORE:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fhire\u002FFETCH_MORE",
                      RESET:
                        "@\u002Fview\u002Fteam\u002FdetailList\u002Fhire\u002FRESET",
                    },
                  },
                },
              },
              couponList: { list: { 0: u, 1: u, 2: u }, showTooltip: a },
              payment: {
                selectedDiscount: {},
                bookletDetail: {},
                coupons: { availables: [], unavailables: [] },
                discountList: [],
              },
              activityVip: { selectedVipSku: {} },
            },
            component: {
              indexAside: {
                bannerList: [],
                userList: [],
                actionType: {
                  FETCH_BANNER: "@\u002Fcomponent\u002Faside\u002FFETCH_BANNER",
                  FETCH_USER: "@\u002Fcomponent\u002Faside\u002FFETCH_USER",
                  CLOSE_BANNER: "@\u002Fcomponent\u002Faside\u002FCLOSE_BANNER",
                },
              },
            },
            ore: { oreCount: b },
            avatarMenuInfo: {
              user_basic: {},
              user_counter: {},
              user_growth_info: {},
            },
            common: { theme: "light" },
            env: { ua: p, serverEnv: "production" },
            auth: {
              user: c,
              clientId: e,
              token: e,
              qrCode: c,
              qrCodeStatus: c,
              qrCodeToken: c,
            },
            tag: { subscribedTagList: [] },
            entry: { isLikeLoading: a },
            collection: {},
            comment: {},
            bookComment: {},
            repoComment: {},
            category: { list: [] },
            user: { subscribedTagList: [] },
            notification: { unreadCount: { user: b, system: b, total: b } },
            follow: { subscribedTagList: [] },
            error: {
              location: c,
              errorView: c,
              statusCode: 200,
              needRiskModal: a,
              riskAppealUrl: e,
            },
            abTest: { info: {} },
            suspensionPanel: { needSuspension: d },
            pinComment: {},
            pin: {
              deleteDialogVisible: a,
              reportDialogVisible: a,
              targetPin: c,
              isOnFocus: a,
            },
            topic: { visible: a },
            activity: {
              2020: {},
              offer: { is_show: b, start_time: b },
              voteData: {
                err_no: b,
                err_msg: "success",
                data: {
                  face: {
                    title: e,
                    activity_id: "7",
                    start_time: 1681142400,
                    end_time: 1681920000,
                    status: g,
                    image:
                      "https:\u002F\u002Fp6-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002Fa5f031a954eb4fe78b3d5da1aeea0c9f~tplv-k3u1fbpfcp-zoom-1.image",
                    close_image:
                      "https:\u002F\u002Fp3-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002F882fc263e36347ffbf6d598de520870e~tplv-k3u1fbpfcp-image.image",
                    url: "https:\u002F\u002Fjuejin.cn\u002Fpost\u002F7220351836331425847?utm_source=popup&utm_medium=app&utm_campaign=j3y4",
                    is_show: g,
                  },
                  top: {
                    title: v,
                    activity_id: k,
                    start_time: w,
                    end_time: x,
                    status: i,
                    image:
                      "https:\u002F\u002Fp3-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002F9563d620af3b48a791f77019c948f064~tplv-k3u1fbpfcp-zoom-1.image",
                    close_image:
                      "https:\u002F\u002Fp3-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002Ff49fe994db7b4af7846259d97610bec0~tplv-k3u1fbpfcp-zoom-1.image",
                    url: "https:\u002F\u002Fjuejin.cn\u002Fvip?utm_source=app_top",
                    is_show: b,
                  },
                  web_top: {
                    title: v,
                    activity_id: k,
                    start_time: w,
                    end_time: x,
                    status: i,
                    image: L,
                    close_image:
                      "https:\u002F\u002Fp3-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002F19e7f58eecbd497c92397344e1d489a6~tplv-k3u1fbpfcp-zoom-1.image",
                    url: "https:\u002F\u002Fjuejin.cn\u002Fvip?utm_source=web_nav",
                    is_show: b,
                  },
                  plugin_top: {
                    title: v,
                    activity_id: k,
                    start_time: w,
                    end_time: x,
                    status: i,
                    image: L,
                    close_image: y,
                    url: "https:\u002F\u002Fjuejin.cn\u002Fvip?utm_source=gold_browser_extension",
                    is_show: b,
                  },
                  search_top: {
                    title: M,
                    activity_id: k,
                    start_time: N,
                    end_time: 1675612799,
                    status: i,
                    image: O,
                    close_image: P,
                    url: Q,
                    is_show: b,
                  },
                  web_search: {
                    title: M,
                    activity_id: k,
                    start_time: N,
                    end_time: 1675612800,
                    status: i,
                    image: O,
                    close_image: P,
                    url: Q,
                    is_show: b,
                  },
                  jcode_top: {
                    title: "码上掘金编程挑战赛",
                    activity_id: k,
                    start_time: 1670846400,
                    end_time: 1671983999,
                    status: i,
                    image: y,
                    close_image: y,
                    url: "https:\u002F\u002Fjuejin.cn\u002Fchallenge?utm_source=code_nav",
                    is_show: b,
                  },
                  offer: {
                    title: e,
                    activity_id: "2020",
                    start_time: 1617638400,
                    end_time: 1618934400,
                    status: i,
                    image:
                      "https:\u002F\u002Fp9-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002F2879410508de459c91ae8b7509ca75f8~tplv-k3u1fbpfcp-zoom-1.image",
                    close_image:
                      "https:\u002F\u002Fp9-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002Fa38d640009e14c87a7d29cd95dee27dd~tplv-k3u1fbpfcp-zoom-1.image",
                    url: "https:\u002F\u002Fjuejin-activity.bytedance.net\u002Frank",
                    is_show: b,
                  },
                },
              },
            },
            header: { leadStep: b, isPopupZlink: a },
            tcc: { tccConfig: c },
            route: {
              name: "column",
              path: z,
              hash: e,
              query: {},
              params: { id: m },
              fullPath: z,
              meta: {},
              from: {
                name: c,
                path: R,
                hash: e,
                query: {},
                params: {},
                fullPath: R,
                meta: {},
              },
            },
          },
          serverRendered: d,
          routePath: z,
          config: {
            API_HOST: "api.juejin.cn",
            CAPTCHA_HOST: "verify.snssdk.com",
            PLATFORM_APPID: {
              wechat: 1277,
              weibo: 1276,
              github: 1045,
              wechatApp: 1070,
            },
            SCM_VERSION: "1.0.0.6855",
            http: {},
          },
          globalRefs: {},
        };
      })(
        false,
        0,
        null,
        true,
        "",
        "0",
        1,
        20,
        2,
        "topic",
        "2022",
        "recommended",
        "6950084496515399717",
        "hot",
        "newest",
        void 0,
        "following",
        "popular",
        398,
        5,
        {},
        "掘金会员",
        1673020800,
        1680278400,
        "https:\u002F\u002Fp6-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002F759e2aa805c0461b840e0f0f09ed05fa~tplv-k3u1fbpfcp-zoom-1.image?",
        "\u002Fpost\u002F6950084496515399717",
        "1028798616461326",
        "Vue 源码解读（2）—— Vue 初始化过程",
        "详细讲解了 Vue 的初始化过程都做了哪些事 ...........................",
        "6940043781823528974",
        38400,
        358,
        145,
        "李永宁",
        19301,
        {},
        100,
        "https:\u002F\u002Fp3-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002F7482b3ad2cd14edda31f05399c2ae759~tplv-k3u1fbpfcp-zoom-1.image",
        "开启我的2022年度报告",
        1672797600,
        "https:\u002F\u002Fp1-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002F8a41831fce8b4c838f1807b2c86aea06~tplv-k3u1fbpfcp-zoom-1.image",
        "https:\u002F\u002Fp9-juejin.byteimg.com\u002Ftos-cn-i-k3u1fbpfcp\u002Fe5199830276c4a85bc7c8cb8edecd54d~tplv-k3u1fbpfcp-image.image",
        "https:\u002F\u002Fjuejin.cn\u002Freport2022\u002Fmobile?utm_source=search",
        "\u002F"
      );
    </script>
    <script
      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/10e5709.js"
      defer
    ></script>
    <script
      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/d61db58.js"
      defer
    ></script>
    <script
      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/33abca8.js"
      defer
    ></script>
    <script
      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/65b1426.js"
      defer
    ></script>
    <script
      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/990892a.js"
      defer
    ></script>
    <script
      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/956677f.js"
      defer
    ></script>
    <script
      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/24eeb15.js"
      defer
    ></script>
    <script
      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/9928f25.js"
      defer
    ></script>
    <script
      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/e77ab26.js"
      defer
    ></script>
    <script
      src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/26ba7b3.js"
      defer
    ></script>
  </body>
</html>
